You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将指定SQL查询转换为正确的Rails Scope?

问题分析与解决方案

你当前定义的free scope无法选中未关联SlotAlteration的Slot,核心原因是where.not(alterations: { action: 1 })的SQL逻辑问题:当Slot没有关联的SlotAlteration时,slot_alterations.action的值为NULL,而SQL中NULL != 1的运算结果是未知,这类记录会被where条件自动排除,导致符合要求的无关联Slot被过滤掉。

以下是两种符合原SQL逻辑的正确scope写法:

写法一:对应原SQL的NOT EXISTS子查询

直接复刻原SQL的NOT EXISTS逻辑,精准筛选出不存在action=1的关联SlotAlteration的Slot:

scope :free, -> {
  where(time_off_id: nil)
    .where.not(
      exists(
        SlotAlteration.select(1).where("slot_alterations.slot_id = slots.id").where(action: 1)
      )
    )
    .order(id: :asc)
}

写法二:使用分组统计过滤

通过left_joins关联所有可能的SlotAlteration,按Slot分组后统计action=1的记录数,只保留统计数为0的(包含无关联的Slot):

scope :free, -> {
  left_joins(:alterations)
    .where(time_off_id: nil)
    .group("slots.id")
    .having("COUNT(CASE WHEN slot_alterations.action = 1 THEN 1 END) = 0")
    .order(id: :asc)
}

两种写法均能满足需求:返回time_off_id为null,且不存在关联action=1的SlotAlteration的Slot(包括完全没有关联SlotAlteration的记录)。

内容的提问来源于stack exchange,提问作者RomanMin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 10:55:03