Reputation: 303
I'm currently having a hard time finding a solution for a problem I have in a Ruby on Rails project.
I have the following model structure:
class Room < ActiveRecord::Base
has_many :photos
end
class Photo < ActiveRecord::Base
belongs_to :room
has_many :points
end
class Point < ActiveRecord::Base
belongs_to :photo
end
I want to query the database so that I get something that rendered as JSON would have this structure:
{
"rooms" :
[
//room 1
{
"id": 1,
"param1": "dummy",
"photos":
[
{
"id": 3,
"title": "test photo",
"points":
[
{"id": 1, "text": "test point"},
{"id": 2, "text": "test point"}
]
}
]
},
//room 2
{
"id": 2,
// ...
}
]
}
Basically, I want to make a query that returns all the info, in all the models, structured according to the models relations.
I searched for a couple of hours and can't find any simple solution for this... (not even complicated one). I don't know if I'm not using the correct search keywords for my problem, but I really couldn't find anything that works...
For a partial solution (to get only rooms and photos), I tried this:
Room.all.includes(:photos)
From what I found, I thought it could be the solution, but it just returns the information about the rooms, not the photos, so probably this is a totally different approach to the one I need.
Upvotes: 1
Views: 188
Reputation: 487
@dankohn's answer is correct for eager loading nested associations, but I believe you need a bit more for it to work with to_json. The issue i believe is to_json just looks at the original set of objects and doesn't know about the eager loaded associations. But luckily to_json is a method call that can take the includes as a set hash of options. (Had an issue at in the original code that @norim_13 helped correct. Thanks!!)
Room.all.to_json({:include => { :photos => {:include => { :points => {}} }}})
https://www.tigraine.at/2011/11/17/rails-to_json-nested-includes-and-methods Rails: Eager loading as_json includes
Here is the documentation for as_json http://apidock.com/rails/ActiveModel/Serializers/JSON/as_json
and here in the source for to_json you can see it passes its hash of options to as_json http://apidock.com/rails/Hash/to_json
Upvotes: 3
Reputation: 186
If you get to breaking point, it might be easier just writing a series of .each loops and then just building up the json string manually around them..
Room.all.each do |room|
room.photos.each do |photo|
photo.points.each do |point|
// inner loop
end
end
end
Upvotes: 0
Reputation: 34337
Revised:
What do you get with:
Room.all.includes(photos: :points).to_json
For more info, see Rails - Nested includes on Active Records?
Upvotes: 1