आपका प्रश्न शायद चौराहे के बिना हल किया जा सकता है, कुछ ऐसा:
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 ...
आप किसी भी स्थिति/जुड़ने आदि के आधार पर उपरोक्त दृष्टिकोण के साथ जितनी आवश्यक हो उतनी सबक्वेरी बना सकते हैं, जब तक कि प्रत्येक सबक्वेरी अपने परिणाम सेट में मेल खाने वाले व्यक्ति की आईडी लौटा दे।
प्रत्येक सबक्वेरी परिणाम सेट को एक साथ AND'ed किया जाएगा और इस प्रकार मिलान सेट को सभी सबक्वेरी के प्रतिच्छेदन तक सीमित कर दिया जाएगा।
अपडेट करें
AR4 का उपयोग करने वालों के लिए जहां scoped
हटा दिया गया था, मेरा अन्य उत्तर शब्दार्थ रूप से समतुल्य scoped
. प्रदान करता है पॉलीफिल जो all
एआर दस्तावेज जो सुझाव देता है उसके बावजूद समकक्ष प्रतिस्थापन नहीं है। यहां उत्तर दें:रेल 4 के साथ, Model.scoped पदावनत है लेकिन Model.all इसे प्रतिस्थापित नहीं कर सकता