其中has_many通过
问题描述:
给定Car
有许多features
它们通过listed_features
连接。我如何才能找到所有cars
其中features
与ids
1
和2
和3
? cars
可以有更多的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。
这是否保证车具有功能1和2和3? 'id:id_list'基本上会做1或2或3,计数只能确保有三个特征。功能3,4,5的汽车是否与此查询匹配? – Mischa
这是功能表中具有这些ID和哪些连接到汽车表行的行数的计数。因此,如果汽车至少具备所需的功能,汽车将被退回。任何其他功能的存在将被忽略。 –
啊,是的,我现在看到了。谢谢。 – Mischa