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
相关产品推荐
相关产品推荐

