我有这个型号:
class Product < ActiveRecord::Base
belongs_to :shop
has_many :categories_products, dependent: :destroy, autosave: true
has_many :categories, through: :categories_products
has_many :favorite_products, dependent: :destroy
has_many :users, through: :favorite_products
scope :by_shop_category, ->(shop_id, category_id) { eager_load(:categories_products).where(shop_id: shop_id, categories_products: {category_id: category_id}) }
scope :by_category, ->(category_id) { eager_load(:categories_products).where(categories_products: {category_id: category_id}) }
我有这两个查询:
favorite_products = Product.where(id: current_user.product_ids).by_category(@category.id)
favorite_shop_products = Product.by_shop_category(current_user.shop_ids, @category.id)
第一个返回当前用户从某个类别中收藏的所有产品。第二个返回当前用户最喜欢的所有商店中某个类别的所有产品。
显然,如果用户偏爱了属于他们所偏爱的商店的产品,那么该产品将会出现在两个产品组中。
什么是提供一系列独特结果的最干净的高效工作方式?
答案 0 :(得分:0)
favorite_products | favorite_shop_products
使用Array
union运算符组合两个集合并消除重复。根据结果集的大小,这可能是也可能不是高效的。
答案 1 :(得分:0)
我认为这是最简单,性能最高的选项,因为它使用SQL来排除:
favorite_products = Product.where(id: current_user.product_ids).by_category(@category.id)
favorite_shop_products = Product.where.not(id: current_user.product_ids).by_shop_category(current_user.shop_ids, @category.id)
@products = favorite_products + favorite_shop_products