我有两个模型Invoice
和InvoiceEvent
Invoice
有很多InvoiceEvents
InvoiceEvent
有一个字段state
我想写一个查询来查找没有Invoices
的所有InvoiceEvent
state = 'paid'
我的第一次尝试是
Invoice.joins(:events).where("invoice_events.state != 'paid'")
但这简直抓住了所有发票,因为付费发票仍会有其他事件导致付费事件。
答案 0 :(得分:3)
首先,您希望做的所有InvoiceEvent
状态为'paid'
:
InvoiceEvent.where(:state => 'paid')
从那里你可以获得具有这种状态的事件的Invoice
:
InvoiceEvent.where(:state => 'paid').select(:invoice_id)
然后,您可以使用子查询查找该列表中不包含的所有Invoice
:
Invoice.where.not(
:id => InvoiceEvent.where(:state => 'paid').select(:invoice_id)
)
请注意select(:invoice_id)
来电。 ActiveRecord会将其转换为子查询,如:
where id not in (select invoice_id from ...)
这样数据库就可以完成这项工作而无需在Rails-land中提取大量数据,只是将其发送回数据库。