ruby-on-rails - 查找所有子记录与给定列表完全匹配的所有父母,在 Rails 中通过关联有很多
问题描述
我有以下关系
class Invoice
has_many :entries
has_many :price_matrixes, through: entries
end
class Entry
belongs_to :invoice
belongs_to :price_matrix
end
class PriceMatrix
has_many :entries
has_many :invoices, through: entries
end
现在,我有一组 price_matrix id,例如 [1, 2],并且我想找到只有这两个价格矩阵的所有发票。
注意:试过这个Invoice.includes(:price_matrixes).where(price_matrixes: {id: [1, 2]})
,但这应该返回记录,即使列表中的一个 id 将匹配。
解决方案
使用简单的 SQL 可以轻松解决该任务。假设您使用 PostgreSQL 9+,这是用于获取符合您的条件的发票 ID 的 SQL 查询(仅具有带有 ID [1、2] 的完全价格矩阵):
SELECT I.id
FROM invoices I
JOIN entries E ON E.invoice_id = I.id
GROUP BY I.id
HAVING array_agg(E.price_matrix_id ORDER BY E.price_matrix_id ASC) = ARRAY[1,2];
在这里,我们加入invoices
和entries
,对结果进行分组invoice.id
,并只过滤那些已经给出的结果price_matrix_ids
。请注意,ARRAY[1,2]
表达式应包含price_matrix_ids
按升序排序的内容。
在线演示:http ://rextester.com/TAEUU9220
回到 Ruby,代码如下:
price_matrix_ids = [1,2].sort
Invoice.joins(:entries).having("array_agg(entries.price_matrix_id ORDER BY entries.price_matrix_id ASC) = ARRAY[#{price_matrix_ids.join(',')}]").group('invoices.id')