Rails具有关联记录符合条件的任意位置(_many)



在这个(简化的(系统中,

class Order
has_one :bill
...
end

class Bill
has_many :rebills
belongs_to :order
...
end
class Rebill
belongs_to :bill
...
end

BillRebill都有一个status列,它可能处于各种状态之一,有些状态等同于成功,有些状态则等同于失败。

我目前正在查找所有没有成功付款的Order记录。如果关联的Bill记录处于失败状态,并且Bill记录没有处于成功状态的关联Rebill记录,则订单符合我的条件。

如果一个Order有一个失败的Bill,一个也失败了的Rebill,还有第二个成功的Rebill,那么Order已经付款了,我对此不感兴趣

如果一个Order有一个失败的Bill,并且没有相关的Rebills,那么它没有成功的付款,并且我对此感兴趣。

如果一个Order有一个失败的Bill,并且任何数量的Rebills处于失败状态(但没有一个处于成功状态(,那么就没有成功的支付,我对此感兴趣。

因此,我的问题是,如何构建一个查询,返回所有没有成功付款的Order记录?这里真正的问题是,我认为在多个地方成功付款是不好的。然而,我觉得我应该能够低声说出正确的SQL咒语来做到这一点,但join、where、have和count的数量让我难以置信!

有人知道我在这里想做什么吗?如果有,我会怎么做?

这并没有那么复杂。首先,让我们查找Bill记录处于失败状态的所有Order记录。

Order.joins(:bill).where(bills: { state: "failed" })

现在,让我们确保对于Bill,不存在处于成功状态的Rebill

Order.joins(:bill).where(bills: { state: "failed" })
.where("NOT EXISTS(SELECT 1 FROM rebills 
WHERE bill_id = bills.id 
AND rebills.state = successful)")

您可能可以用更ActiveRecord的方式编写NOT EXISTS查询,我通常会放弃,转而使用原始SQL。

DB小提琴连接。

应该这样做。

# rebills contains all rebills with a successful payment
rebills = Rebill.where(status: 'successful')
# bills contains bills without a successful payment
# that are not associated with the above described rebills 
bills = Bill.where.not(status: 'successful', id: rebills.select(:bill_id))
# orders contains orders that are associated with the above described bills
orders = Order.where(id: bills.select(:order_id))

当加载orders时,上面应该执行一个查询。

注意:当复制到控制台后缀中时,带有;nil的行将阻止inspect方法(用于显示控制台返回值(加载集合。

最新更新