如何从目标产品集合中筛选无snacks_case关联的Spree产品?
解决方案
你可以通过左连接+空值筛选的方式,从已过滤的产品集合中获取不存在snacks_case关联的产品,具体实现如下:
完整代码
# 1. 获取餐厅产品并筛选非ESS(external_product_source != 0)或字段为NULL的产品 products = restaurant.products.where('external_product_source != ? OR external_product_source IS NULL', 0) # 2. 筛选出没有snacks_case关联的产品 products_without_snacks_case = products.left_joins(:snacks_case).where(spree_product_sets: { id: nil })
代码解释
left_joins(:snacks_case):执行左连接操作,将产品表与对应snacks_case关联的Spree::ProductSet表连接。左连接会保留所有已过滤的产品,即使该产品没有对应的snacks_case记录,此时Spree::ProductSet的字段会为NULL。where(spree_product_sets: { id: nil }):筛选出那些没有匹配到snacks_case记录的产品,也就是不存在该关联的目标产品。
替代实现(子查询方式)
如果更倾向于用子查询,也可以这样写:
products_without_snacks_case = products.where.not( id: Spree::ProductSet.snacks_case.where(source_type: 'Spree::Product', source_id: products.select(:id)).select(:source_id) )
这个逻辑是:先找出所有已存在snacks_case关联的产品ID,再从已过滤的集合中排除这些ID,得到没有关联的产品。
内容的提问来源于stack exchange,提问作者Humayun Naseer
相关产品推荐
相关产品推荐

