在Rails中使用includes()而不是join()

时间:2014-11-19 16:40:33

标签: sql ruby-on-rails

我有两个模型invoicepayevents。它们之间的关系为invoice has_many payevents

我正在使用以下查询来获取已全额付款的所有帐单。:

Invoice.joins(:payevents).group("invoice.id").having("sum(payevents.amount) >= invoice.amount")

此查询正常。但是,它不是最佳的,因为结果不包括payevents。我尝试使用includes代替joins,但它不起作用。

Invoice.includes(:payevents).group("invoice.id").having("sum(payevents.amount) >= invoice.amount")

错误是

ActiveRecord::StatementInvalid: PG::GroupingError: ERROR:  column "payevents.id" must appear in the GROUP BY clause or be used in an aggregate function

这里有什么问题吗?

我使用PostgreSQL和Rails 4.1

2 个答案:

答案 0 :(得分:1)

如果我正确理解你 - 你应该使用子查询。像这样:

subquery = Invoice.joins(:payevents)
                  .group("invoice.id")
                  .having("sum(payevents.amount) >= invoice.amount")
                  .select("invoice.id id, sum(payevents.amount) amount").to_sql

query = Invoice.includes(:payevents).joins("JOIN (#{subquery}) subquery ON invoice.id = subquery.id")

因此,您将拥有Invoice,汇总金额,通过子查询的内部联接和所有payevents字段筛选结果。

答案 1 :(得分:0)

更简单的解决方案是明确使用preload

Invoice.joins(:payevents).group("invoice.id").having("sum(payevents.amount) >= invoice.amount").preload(:payevents)