あなたの質問はおそらく交差することなく解決可能です:
Person.joins(:services).where(services: {service_type: [1,2]}).group(
people: :id).having('COUNT("people"."id")=2')
ただし、以下は、ActiveRecordでクエリのような交差点を構築するために使用する一般的なアプローチです。
class Service < ActiveRecord::Base
belongs_to :person
def self.with_types(*types)
where(service_type: types)
end
end
class City < ActiveRecord::Base
has_and_belongs_to_many :services
has_many :people, inverse_of: :city
end
class Person < ActiveRecord::Base
belongs_to :city, inverse_of: :people
def self.with_cities(cities)
where(city_id: cities)
end
def self.with_all_service_types(*types)
types.map { |t|
joins(:services).merge(Service.with_types t).select(:id)
}.reduce(scoped) { |scope, subquery|
scope.where(id: subquery)
}
end
end
Person.with_all_service_types(1, 2)
Person.with_all_service_types(1, 2).with_cities(City.where(name: 'Gold Coast'))
次の形式のSQLが生成されます:
SELECT "people".*
FROM "people"
WHERE "people"."id" in (SELECT "people"."id" FROM ...)
AND "people"."id" in (SELECT ...)
AND ...
各サブクエリが結果セットで一致する人物のIDを返す限り、任意の条件/結合などに基づいて、上記のアプローチで必要な数のサブクエリを作成できます。
各サブクエリの結果セットはANDで結合されるため、一致するセットはすべてのサブクエリの共通部分に制限されます。
更新
scoped
でAR4を使用している場合 削除されましたが、他の回答は意味的に同等のscoped
を提供します all
のポリフィル ARのドキュメントが示唆していることにもかかわらず、は同等の代替品ではありません。ここで回答: Rails 4では、Model.scopedは非推奨ですが、Model.allで置き換えることはできません