Question

I am creating a rails app that has users and classes. The classes are a three way join table composed of a teacher, subject, and period. I have created another many to many relationship between Classrooms and Users, so that a classroom can have many users and a user can have many classrooms.

As well as the rails app, I have created an API so that my app can interact with an iPhone app. My problem arises when I create a user with a couple of classrooms. Everything works fine on the rails side, because for each classroom, I can get the subject, teacher, or period through classroom.subject (or the corresponding key). When I create a user with the API, I am trying to respond with the users classrooms.

If I simply do @user.to_json(:include => :classrooms), it responds with a classroom object that just has the IDs for teacher, subject, and period. With out the ability to do classroom.teacher, this is pretty useless. How would I go about responding with the classroom, including the subject, teacher, and period objects? This way on the IOS side, I can just create a dictionary for the class object, and just interact with it without having to do a request to get the values for teacher, subject, and period.

Here is what I respond with when a user is created:

format.json { render json: @user.to_json(:include => :classrooms) }

Here is how a classroom is created:

@classroom = Classroom.where(:teacher_id => @new_teacher.id,
                                              :period_id => @new_period.id,
                                              :subject_id => @new_subject.id).first_or_create

After taking into account Threeve's answer and including render :json => @user.to_json(:include => {:classrooms => [:teacher, :period, :subject]}) in my response, I get the following error:

TypeError (no implicit conversion of Symbol into Integer):
  app/controllers/api/v1/user_controller.rb:103:in `block (2 levels) in create'
  app/controllers/api/v1/user_controller.rb:102:in `create'
Était-ce utile?

La solution

Have you tried chaining the deeper associations onto the #to_json :include option?

What does it look like when you do something like this?

format.json {
  render :json => @user.to_json(:include => {:classrooms => {:include => [:teacher, :period, :subject]}})
}

That should get you the complete records for the teacher/period/subject associations.

If you wanted to be specific about which associated attributes are displayed or ignored, just make the options a little more ugly by adding :only and :except options:

format.json {
  render :json => resource.to_json(:include => { classrooms: {
    :include => {
      :teacher => {:only => [:first_name, :last_name]},
      :period => {:except => :time},
      :subject => {:only => :name}
    }
  }})
}

Other options include creating a hash then converting it to JSON, rendering to a JSON partial with plain ERB, or perhaps using RABL or JBuilder.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top