其中has_many通过

问题描述:

给定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 

诀窍这里可能是声明,你需要从功能表三场比赛。

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