56

Right now I have this line:

 render json: @programs, :except => [:created_at, :updated_at]

However, since a Program belongs_to a Company I would like to show the Company name instead of the Company Id.

How can I include the company name when rendering Programs?

2
  • Can we see the model? Commented Jul 18, 2013 at 17:25
  • possible duplicate: stackoverflow.com/questions/7506089/… Commented Jul 18, 2013 at 17:41

6 Answers 6

93

Something like this should work:

render :json => @programs, :include => {:insurer => {:only => :name}}, :except => [:created_at, :updated_at]
Sign up to request clarification or add additional context in comments.

2 Comments

I still don't understand... any documentation on how to do this?
20

i was getting the same "can't clone Symbol file" error while rendering json with includes from a controller method. avoided it like so:

render :json => @list.to_json( :include => [:tasks] )

Comments

13

You can also do this at the model level.

program.rb

  def as_json(options={})
    super(:except => [:created_at, :updated_at]
          :include => {
            :company => {:only => [:name]}
          }
    )
  end
end

Now in your controller:

render json: @programs

Comments

9

Consider using jbuilder to include nested models in a maintainable way:

# /views/shops/index.json.jbuilder
json.shops @shops do |shop|

  # shop attributes to json
  json.id shop.id
  json.address shop.address

  # Nested products
  json.products shop.products do |product|
    json.name product.name
    json.price product.price
  end

end  

Comments

4

Try this. Ref

#`includes` caches all the companies for each program (eager loading)
programs = Program.includes(:company)

#`.as_json` creates a hash containing all programs
#`include` adds a key `company` to each program
#and sets the value as an array of the program's companies
#Note: you can exclude certain fields with `only` or `except`
render json: programs.as_json(include: :company, only: [:name])

Also, no need to make @programs an instance variable, as I'm assuming we are not passing it to a view.

Comments

0
#includes is used to avoid n+1 query.
# http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations
Here is an example for the above example.Lets say you have posts and each post has many comments to it.

  @posts = Post.where('id IN [1,2,3,4]').includes(:comments)
  respond_to do |format|
     format.json {render json: @posts.to_json(:include => [:comments]) }
  end

  #output data
  [
    {id:1,name:"post1",comments:{user_id:1,message:"nice"}}
    {id:2,name:"post2",comments:{user_id:2,message:"okok"}}
     {id:3,name:"post1",comments:{user_id:12,message:"great"}}
    {id:4,name:"post1",comments:{user_id:45,message:"good enough"}}
  ]

2 Comments

I think you meant to use a comma: @posts, include: :comments. I believe you will get an error if you try to execute posts as a function with parameters ie @posts(
I can see you edited the code to include to_json so I assume that's why it now works and the old code of @posts(:include => [:comments]) didn't work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.