Wednesday, November 18, 2009

nested relations in ActiveRecord

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?

http://joshsharpe.com/archives/56

No comments: