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

如何通过Rails关联查询获取主订单为活跃状态的子订单?

问题描述

我设计了Purchase模型的自关联结构,代码如下:

class Purchase < ApplicationRecord
  has_one :sub_purchase, class_name: 'Purchase', dependent: :destroy
  belongs_to :main_purchase, class_name: 'Purchase', foreign_key: 'purchase_id', optional: true
end

Purchase模型拥有status属性,其值可能为'active'。我希望查询所有主订单状态为'active'的子订单。

我尝试过如下查询语句,但未达到预期效果:

Purchase.where.not(purchase_id:nil).where(main_purchase: {status: 'active'})

另外我知道可以通过SQL联表查询实现,语句如下:

SELECT *
FROM purchases p1 INNER JOIN purchases p2 ON p2.id = p1.purchase_id
WHERE p2.status='active';

但我希望尽量避免直接编写SQL,寻求基于Rails ORM的实现方案。

解决方案

你可以通过Rails的joins方法结合已定义的关联来实现,无需编写原生SQL:

Purchase.joins(:main_purchase).where(main_purchase: { status: 'active' })

细节说明

  • joins(:main_purchase):会自动生成INNER JOIN语句,利用你在belongs_to中定义的关联规则完成自联,同时自动过滤掉没有主订单的记录,所以无需额外写where.not(purchase_id: nil)。
  • where(main_purchase: { status: 'active' }):通过关联名称嵌套条件,Rails会自动处理表别名和字段映射,生成符合需求的WHERE子句。

如果需要更高的代码复用性,还可以结合模型scope实现:

# 在Purchase模型中添加scope
scope :active, -> { where(status: 'active') }

# 查询时复用该scope
Purchase.joins(:main_purchase).merge(Purchase.active)

这种写法可读性更强,后续如果调整active状态的判断逻辑,只需修改scope即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 19:52:10