2015-09-21 75 views
2

給定Car有許多features它們通過listed_features連接。我如何才能找到所有cars其中featuresids123cars可以有更多的features,但他們必須有前三個features其中has_many通過

的設置:

rails g model Car name:string 
rails g model Feature name:string 
rails g model ListedFeature car:references feature:references 

應用程序/模型/ car.rb

class Car < ActiveRecord::Base 
    has_many :listed_features 
    has_many :features, through: :listed_features 
end 

應用程序/模型/ listed_features.rb

class ListedFeature < ActiveRecord::Base 
    belongs_to :car 
    belongs_to :feature 
end 

應用程序/模型/ featur es.rb

class Feature < ActiveRecord::Base 
end 

回答

3

訣竅這裏可能是聲明,你需要從功能表三場比賽。

id_list = [1, 2, 3] 

Car.joins(:features). 
    where(features: { id: id_list }). 
    references(:features). 
    group(:id). 
    having("count(*) = ?", id_list.size) 

另一種方法是對has_feature上車一個範圍:

def self.has_feature(feature_id) 
    where(CarFeature.where("car_features.car_id = cars.id and car_features.feature_id = ?", feature_id).exists) 
end 

然後,您可以:

Car.has_feature(1).has_feature(2).has_feature(3) 

...或使其與其他類的方法更優雅接受一系列功能,然後多次爲您應用has_feature範圍。

它會生成非常有效的SQL。

+0

這是否保證車具有功能1和2和3? 'id:id_list'基本上會做1或2或3,計數只能確保有三個特徵。功能3,4,5的汽車是否與此查詢匹配? – Mischa

+0

這是功能表中具有這些ID和哪些連接到汽車錶行的行數的計數。因此,如果汽車至少具備所需的功能,汽車將被退回。任何其他功能的存在將被忽略。 –

+0

啊,是的,我現在看到了。謝謝。 – Mischa