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