あなたの質問は、おそらく次のような交差なしで解決できます。
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 で結合されるため、一致するセットがすべてのサブクエリの共通部分に制限されます。
アップデート
削除されたAR4を使用している場合scoped
、私の他の回答は意味的に同等のscoped
ポリフィルを提供しますall
が、ARのドキュメントが示唆しているものにもかかわらず、同等の代替品ではありません。ここで答えてください: Rails 4 では、Model.scoped は廃止されましたが、Model.all はそれを置き換えることはできません