我得到了一个带有 has_many Types 表和几个范围的产品模型:
class Product < ActiveRecord::Base
has_many :product_types
has_many :types, through: :product_types
scope :type1, -> { joins(:types).where(types: { name: "Type1" }) }
scope :type2, -> { joins(:types).where(types: { name: "Type2" }) }
end
当我尝试使用一个范围(例如 Product.type1)时一切顺利,但一次有两个范围(Product.type1.type2)返回一个空查询。是的,一种产品可能有多种类型。
最终目标是使用复选框形式按类型创建产品过滤器。当我检查 type1 和 type2 时,我想查看我所有同时具有 Type1 和 Type1 的产品。
更新 1
所以我尝试做几个查询,然后按照@aaron.v 的建议 & 他们。我想做函数内部的逻辑,所以:
def products_by_type_name(types)
all_types = types.each { |type| Product.joins(:types).where(types: { name: type }).distinct }
...
end
我的意思是遍历每种类型,收集所有产品,然后在函数中使用它们。问题是当我迭代时,每个循环都返回字符串而不是哈希数组。
Product.joins(:types).where(types: { name: types }).distinct # returns array of hashes, it's okay.
types.each { |type| Product.joins(:types).where(types: { name: type }).distinct } # each loop returns string (Type name) instead of array of hashes.
我究竟做错了什么?
解决方案 1
由@aaron.v 建议,解释如下
def self.by_type_name(types)
product_ids = []
types.each do |t|
product_ids << (joins(:types).where(types: { name: t }).distinct.select(:id).map(&:id))
end
find(product_ids.inject(:&))
end
解决方案 2
在reddit上找到。在此功能中,您将获取至少具有一种所需类型的所有产品,而不是仅对具有所需类型计数的产品进行分组。因此,您只能同时获得属于每种类型的产品。
def self.by_type_name(types)
joins(:types).where(types: { name: types }).distinct.group('products.id').having('count(*) = ?', types.each.count)
end