在 Rails 上的 Ruby 中创建一个范围,仅当所有关联的实例都符合特定条件时, returns 一个对象的实例

Creating a scope in Ruby on Rails, that returns an instance of an object only if all the associated instances fit a certain condition

我有一个名为 Carts 的 table,与另一个名为 Subcarts 的 table 有 has_many 关系。我想创建一个 return 购物车 table 的所有实例的范围,其中所有关联的子购物车都符合特定条件(例如:subcart.status == 1)。如果与购物车实例相关联的子购物车的状态甚至为 1,则查询不应 return 购物车实例。

scope :cart_bucket, -> {
   includes(:subcarts).
   where.not('subcarts.status = ?', 1).
   references(:subcarts)

我也曾尝试在查询中使用 select,但由于 return 数组数据类型而出现错误 returned。我想将其保留在一个范围内,并且尽可能不创建方法。

您可以 select 来自那些状态不为 1 的子购物车的所有购物车 ID,并将其用作 where 子句以忽略与这些 ID 匹配的所有购物车:

Cart.where('NOT EXISTS (SELECT s.cart_id FROM subcarts s WHERE s.cart_id = carts.id AND s.status = 1)')

ActiveRecord 版本可能会稍有变化:

Cart.where.not(id: Subcart.where(status: 1).select(:cart_id))

生成的 SQL 使用 NOT IN 子句而不是 NOT EXISTS