[英]Rails query for record and latest association record efficiently with includes?
I'm having trouble with a rails activerecord query. 我在使用rails activerecord查询时遇到问题。
I have 2 tables. 我有2张桌子。
One for Projects: 一个项目:
id | name | created_at | updated_at
One for Project Reports: 一个用于项目报告:
id | project_id | number | created_at | updated_at
The corresponding class for Project: Project的相应类:
class Project < ActiveRecord::Base
has_many :project_reports
def latest_report_number
project_reports.last.number
end
end
And ProjectReports: 和ProjectReports:
class ProjectReport < ActiveRecord::Base
belongs_to :project
end
I'm attempting to write a query to get a list of the projects and the most recent report for the project. 我正在尝试编写查询以获取项目列表和该项目的最新报告。
I can do this in the following way, but this leads to a N+1 situation: 我可以通过以下方式执行此操作,但这会导致N + 1情况:
Project
.select("projects.*, max(project_reports.created_at) as latest_report")
.joins(:project_reports)
.order("latest_report desc")
.group("projects.id")
.map { |p| "#{p.name}: #{p.latest_report_number}" }
I therefor wanted to use rails 'includes' feature so that I don't run into the N+1 situation: 因此,我想使用rails的“ includes”功能,以免遇到N + 1情况:
Project
.select("projects.*, max(project_reports.created_at) as latest_report")
.joins(:project_reports)
.order("latest_report desc")
.group("projects.id")
.includes(:project_reports) # <----
.map { |p| "#{p.name}: #{p.latest_report_number}" }
This causes my query to no longer work: 这导致我的查询不再起作用:
PG::GroupingError: ERROR: column "project_reports.id" must appear in
the GROUP BY clause or be used in an aggregate function
How can I write my query so that I both accomplish the goal and limit the number of times I hit the database (ideally with includes)? 如何编写查询,以便既完成目标又限制我访问数据库的次数(理想情况下是包含)?
In the case of a join query, includes
asks for extra columns from the associated table (ie tasks
) in order to build the associated objects without an additional query. 在联接查询的情况下,
includes
要求从关联的表中获取额外的列(即tasks
),以便在没有附加查询的情况下构建关联的对象。 Normally, that's a welcome optimization, but in the case of a GROUP BY
clause, you wind up with an invalid SELECT
. 通常,这是一个受欢迎的优化,但是在使用
GROUP BY
子句的情况下,您将获得无效的SELECT
。
In your case, you want a completely separate query to load the associations, so preload
is a better choice. 在您的情况下,您希望使用完全独立的查询来加载关联,因此
preload
是一个更好的选择。
Project
.select("projects.*, max(project_reports.created_at) as latest_report")
.joins(:project_reports)
.order("latest_report desc")
.group("projects.id")
.preload(:project_reports)
.map { |p| "#{p.name}: #{p.latest_report_number}" }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.