私は 3 つの単純なモデルを持っています。それらをセクター、部門、オフィスと呼びましょう。セクターには多くの部門があり、部門には多くのオフィスがあります。
ここで、少なくともオフィスがある少なくとも部門を持つすべてのセクターを取得したいと考えています。
私はいくつかの異なる方法を試しましたが、それらは「多かれ少なかれ」機能します。Sector.with_offices を呼び出すと、必要なものが得られますが、.size (元のクエリにカウントを追加する) などのかなり一般的なメソッドをチェーンすると、予期しない結果が得られます。ここで私が試したこと:
scope :with_offices, joins(:departments => :offices).group('sectors.id')
scope :with_offices, joins(:departments => :offices).select("DISTINCT sectors.*")
私も使ってみましたuniq
:
scope :with_offices, joins(:departments => :offices).uniq
しかし、同じ問題があります。
Sector.with_offices.size # => 5 (WRONG VALUE)
s = Sector.with_offices # => [#<Sector ... >]
s.size # => 3 (RIGHT VALUE)
サイズをチェーンすると、間違った番号が表示されます。
オフィスのあるセクターを取得し、サイズを期待どおりに機能させるためのクリーンな方法は何ですか?
更新 1 - SQL クエリ ここで私のクエリですが、両方の関連付けに状態を制限する条件句があることを忘れていました (以下を参照)。
irb(main):010:0> Sector.with_offices.size
(0.6ms) SELECT DISTINCT COUNT(*) FROM "sectors" INNER JOIN "departments" ON "departments"."sector_id" = "sectors"."id" AND departments.state IN ('active', 'deactivated') INNER JOIN "offices" ON "offices"."department_id" = "departments"."id" AND offices.state IN ('active', 'deactivated') WHERE "sectors"."state" IN ('active', 'deactivated')
=> 5
irb(main):011:0> s = Sector.with_offices
Sector Load (0.6ms) SELECT DISTINCT "sectors".* FROM "sectors" INNER JOIN "departments" ON "departments"."sector_id" = "sectors"."id" AND departments.state IN ('active', 'deactivated') INNER JOIN "offices" ON "offices"."department_id" = "departments"."id" AND offices.state IN ('active', 'deactivated') WHERE "sectors"."state" IN ('active', 'deactivated')
更新 2 - 協会
Class Sector < ActiveRecord::Base
has_many :departments , conditions: ["departments.state IN ('active', 'deactivated')"]
end
Class Department < ActiveRecord::Base
has_many :offices , conditions: ["offices.state IN ('active', 'deactivated')"]
end