如何找到2个独立重叠查询的唯一结果?

时间:2014-05-02 20:55:27

标签: ruby-on-rails activerecord

我有这个型号:

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)

第一个返回当前用户从某个类别中收藏的所有产品。第二个返回当前用户最喜欢的所有商店中某个类别的所有产品。

显然,如果用户偏爱了属于他们所偏爱的商店的产品,那么该产品将会出现在两个产品组中。

什么是提供一系列独特结果的最干净的高效工作方式?

2 个答案:

答案 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