2012-05-05 40 views
0

我想通過以下模型中的酒吧獲取與單個foo關聯的條形記錄,其中 Foo <-> Bar <-> Baz如何在深度關聯中使用ActiveRecord

class Foo < ActiveRecord::Base 
    has_many :foo_bar_assocs 
    has_many :bars, through: :foo_bar_assocs 
end 

class Bar < ActiveRecord::Base 
    has_many :bar_baz_assocs 
    has_many :bazs, through: :bar_baz_assocs 
    attr_readonly :name 
end 

class Baz < ActiveRecord::Base 
end 

class FooBarAssoc < ActiveRecord::Base 
    belongs_to :foo 
    belongs_to :bar 
end 

class BarBazAssoc < ActiveRecord::Base 
    belongs_to :bar 
    belongs_to :baz 
end 

幼稚的做法:

foo = Foo.find(id) 
baz_of_foo = foo.bars.where(name: params[:name]).map{|b| b.bazs}.flatten.uniq 

此代碼生成壞的查詢,它執行了很多次。 我要的是類似如下:

baz_of_foo = foo.something_good_query(bar_name: params[:name]) 

而且,我想,這樣產生的SQL查詢進行優化,以獲得比如ActiveRecord ::關係的對象。

baz_of_foo.each{ ... } # SELECT DISTINCT baz.* FROM ... 
baz_of_foo.count  # SELECT COUNT(DISTINCT baz.*) FROM ... 
baz_of_foo.exists?  # SELECT baz.* FROM ... TAKE 1 

回答

0

你應該定義反向關係也一樣,一旦你這樣做,你應該能夠做這樣的事情:

Baz.joins(:bar => :foo).where(:bar => {:name => params[:name], :foo => {:id => foo_id}}) 

對於複雜的查詢我還建議在squeel gem,它允許用於更緊湊的查詢並支持外部連接。