0

次のモデルの bar を介して、単一の foo に関連付けられた Bar レコードを取得したいと考えています Foo <-> Bar <-> Baz

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::Relation のようなオブジェクトを取得したいと考えています。

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
4

1 に答える 1

0

逆の関係も定義する必要があります。一度定義すると、次のようなことができるはずです。

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

複雑なクエリの場合は、 squeel gemもお勧めします。これにより、よりコンパクトなクエリが可能になり、外部結合もサポートされます。

于 2012-05-06T20:53:04.780 に答える