nested relations in ActiveRecord
13 November 2009 // Filed under active record
I personally don’t think this is all that exciting — but I see this question asked a lot and just want something to point at from now on.
Say you have several ‘nested’ has_many relations:
class State < ActiveRecord::Base has_many :cities end class City < ActiveRecord::Base has_many :streets belongs_to :state end class Street < ActiveRecord::Base has_many :houses belongs_to :city end class House < ActiveRecord::Base belongs_to :street end
How do you get all of the Houses in virginia?
Well, you could do this:
virginia.cities.collect{|c| c.streets}.flatten.uniq.collect{|s| s.houses}.flatten.uniq
... but that's epically lame. It looks like shit and produces an metric ton of queries and as a result is highly inefficient.
How about this:
House.find(
:all,
:include => {:street => {:city => :state}},
:conditions => {'states.id' => virginia.id}
)
This is a single query with joins where appropriate, and it's a finder on House which is what you're getting anyways. Makes sense, no?
2009-11-13 :: admin
17 November 2009 @ 6:50 pm
You can also use the excellent nested_has_many_through plugin.
http://github.com/ianwhite/nested_has_many_through
That will allow you to do
class State :cities
end
>> virginia.houses
I’ve been using it in a big app for over a year. Wish it was included in rails core already.
17 November 2009 @ 6:55 pm
Looks like the html in my last comment did not get encoded correctly. Here it is again:
You can also use the excellent nested_has_many_through plugin.
http://github.com/ianwhite/nested_has_many_through
That will allow you to do
class State < ActiveRecord::Base
has_many :cities
has_many :houses, :through => :cities
end
>> virginia.houses
I’ve been using it in a big app for over a year. Wish it was included in rails core already.
18 November 2009 @ 11:06 am
[...] nested relations in ActiveRecord A nice little tip on using nested attributes with AR [...]
24 November 2009 @ 6:45 pm
[...] nested relations in ActiveRecord | this oughta be interesting… [...]