54

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?

Hommer Smith
  • 26,772
  • 56
  • 167
  • 296

6 Answers6

91

Something like this should work:

render :json => @programs, :include => {:insurer => {:only => :name}}, :except => [:created_at, :updated_at]
Nobita
  • 23,519
  • 11
  • 58
  • 87
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] )
Sean M
  • 1,990
  • 20
  • 16
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
Abram
  • 39,950
  • 26
  • 134
  • 184
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  
Adrien Lamothe
  • 1,477
  • 1
  • 11
  • 14
Arenzel
  • 1,156
  • 1
  • 11
  • 18
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.

IliasT
  • 3,973
  • 1
  • 24
  • 26
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"}}
  ]
user3716986
  • 1
  • 1
  • 3
  • 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(` – Marklar Oct 24 '17 at 03:36
  • 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? – Marklar Nov 13 '17 at 22:55