ActiveRecord:分组包括

ActiveRecord: grouping with includes

我有 3 个模型:Location、UserReview、ContactDetail

位置有很多 user_reviews 并且有很多 contact_details

我想 select 位置为 0 contact_details 的所有位置,并按最后创建的 user_review.

降序排列

我可以 select 所有带有 0 contact_details 的位置,如下所示:

Location
  .includes(:contact_details)
  .where(contact_details: { location_id: nil } )

我可以按最后创建的 user_review 排序所有位置,如下所示:

Location
  .left_joins(:user_reviews)
  .group('locations.id')
  .order('MAX(user_reviews.created_at) DESC')

我在合并这两个查询时遇到了问题。这会引发错误:

Location
  .includes(:contact_details)
  .where(contact_details: { location_id: nil } )
  .left_joins(:user_reviews)
  .group('locations.id')
  .order('MAX(user_reviews.created_at) DESC')

错误:

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

组合这些查询的正确方法是什么?

includes 会在有 where 子句时尝试用 contact_details 创建 LEFT OUTER JOIN,请改用 join

 Location
  .left_outer_joins(:contact_details)
  .left_joins(:user_reviews)
  .group('locations.id')
  .having('COUNT(contact_details.id) = 0')
  .order('MAX(user_reviews.created_at) DESC')

参考:

Rails Guide