在Rails 4中,我与has_and_belongs_to_many
和Car
之间存在一种Color
关系。
给定一组colors
我想找到那些颜色正好的车。我能得到的最接近的是:Car.joins(:colors).where('colors.id' => colors)
,但会返回任何颜色的所有Car
。
我想在ActiveRecord中完全这样做,因为两个表格都很大,所以像Car.joins(:colors).where('colors.id' => colors).to_a.select{|car| car.colors == colors}
这样的东西不太理想。
知道怎么做到这一点吗?
答案 0 :(得分:1)
我能够使用having
和一些粗略的字符串插值SQL来获取它。我把它变成了你可以使用的范围:
# Car.with_exact(colors: colors)
class ActiveRecord::Base
class << self
def with_exact(associations={})
scope = self
associations.each do |association_name, set|
association = reflect_on_association(association_name)
scope = scope.joins(association_name)
.group("#{table_name}.id")
.having("COUNT(\"#{association.join_table}\".*) = ?", set.count)
.having(%{
COUNT(\"#{association.join_table}\".*) = SUM(
CASE WHEN \"#{association.join_table}\".\"#{association.association_foreign_key}\"
IN (#{set.to_a.map(&:quoted_id).join(', ')})
THEN 1 ELSE 0 END
)
}.squish)
end
scope
end
end
end