53

Disclaimer, I know very little about Rails. I'll try to be succinct. Given the following model relations in Rails:

class ModelA < ActiveRecord::Base
  belongs_to :ModelB

...

class ModelB < ActiveRecord::Base
    has_many :ModelA

When calling the show action of the ModelA controller the returned JSON should show all ObjectAs that are children of the ObjectB of which the ObjectA in question is a child of.

So if I have an ObjectB that contains ObjectA's of ID 1, 2 and 3 and then access: /modela/1.json

I should see:

{
  "modelb": {
    "id": "1",
    "modela": [insert the ModelA JSON for ID's 1, 2 and 3]
  }
}
2
  • can you share your controller code (especially the query being performed)? Commented Aug 11, 2010 at 21:11
  • The controller is huge. The query is just @tour = Tour.find(params[:id]) Commented Aug 11, 2010 at 21:20

2 Answers 2

127

By default you'll only get the JSON that represents modelb in your example above. But, you can tell Rails to include the other related objects as well:

def export
  @export_data = ModelA.find(params[:id])
  respond_to do |format|
    format.html
    format.json { render :json => @export_data.to_json(:include => :modelb) }
  end
end

You can even tell it to exclude certain fields if you don't want to see them in the export:

render :json => @export_data.to_json(:include => { :modelb => { :except => [:created_at, updated_at]}})

Or, include only certain fields:

render :json => @export_data.to_json(:include => { :modelb => { :only => :name }})

And you can nest those as deeply as you need (let's say that ModelB also has_many ModelC):

render :json => @export_data.to_json(:include => { :modelb => { :include => :modelc }})

If you want to include multiple child model associations, you can do the following:

render :json => @export_data.to_json(include: [:modelA, :modelB, :modelN...])
Sign up to request clarification or add additional context in comments.

4 Comments

If you want more than one include you add the as an array: @whatever.to_json(include: [:modelA, :modelB, :modelN...]).
If I wanted to call this export function within a view to pull attributes from a specific model, how would I call this?
And what would be the approach, if only ModelA width ID=2 should be included? Is there any other filtering method?
I've been struggling on this for hours... @users = User.includes(:type).all render json: @users doesn't work (even in console I don't see the Type, only type_id ...) @users = User.all render json: @users.to_json(:include => :type) works @users = User.includes(:type).all render json: @users.to_json(:include => :type) doesn't work ¯_(ツ)_/¯ I think I'll stay on Laravel, I've read the Rails manifesto and this is an exemple of what they claim to avoid.
3

If you want a more flexible approach to rendering json, you can consider using the gem jbuilder: https://github.com/rails/jbuilder

It allows you to render custom attributes, instance variables, associations, reuse json partials in a convenient way.

Comments

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.