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

Rails 7中如何编写不干扰其余查询的单WHERE子句OR查询?

Rails 7 中实现目标查询的正确方式

你的需求本质是:满足所有基础过滤条件的前提下,要么quote的approval_date不为空,要么quote的approval_date为空且company_id属于指定集合。

正确的查询代码

Job
  .joins(:quote, :revisions)
  .where.not(revisions: { approved_date: nil })
  .where(billed_date: nil)
  .where(art_billed_date: nil)
  .where(
    quote: { approval_date: nil },
    company_id: companies_to_display
  )
  .or(
    Job
      .joins(:quote, :revisions)
      .where.not(revisions: { approved_date: nil })
      .where(billed_date: nil)
      .where(art_billed_date: nil)
      .where.not(quote: { approval_date: nil })
  )

简化写法(用Arel减少冗余)

如果不想重复编写基础过滤条件,可以用Arel直接组合核心逻辑:

job = Job.arel_table
quote = Quote.arel_table

# 构建核心逻辑:(quote.approval_date IS NOT NULL) OR (quote.approval_date IS NULL AND company_id IN 指定集合)
core_condition = quote[:approval_date].not_eq(nil).or(
  quote[:approval_date].eq(nil).and(job[:company_id].in(companies_to_display))
)

Job
  .joins(:quote, :revisions)
  .where.not(revisions: { approved_date: nil })
  .where(billed_date: nil)
  .where(art_billed_date: nil)
  .where(core_condition)

原写法问题说明

你之前的.or(Job.where(company_id: [companies_to_display]))没有继承前面的joins和基础过滤条件,导致OR右侧是完全独立的Job查询,和左侧查询不共享关联、过滤规则,生成的SQL逻辑会偏离预期。Rails的or方法要求两侧查询必须有相同的关联、字段选择等配置,因此要么重复基础条件构建两侧查询,要么用Arel直接组合条件来精准控制SQL逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:15:01