Commit 70a0a41c authored by Igor Drozdov's avatar Igor Drozdov

Fix N+1 for project/:id/issues API endpoint

Preload milestones and closed_by users
parent f4b8fb60
...@@ -87,11 +87,15 @@ class Issue < ApplicationRecord ...@@ -87,11 +87,15 @@ class Issue < ApplicationRecord
scope :order_created_at_desc, -> { reorder(created_at: :desc) } scope :order_created_at_desc, -> { reorder(created_at: :desc) }
scope :preload_associated_models, -> { preload(:assignees, :labels, project: :namespace) } scope :preload_associated_models, -> { preload(:assignees, :labels, project: :namespace) }
scope :with_api_entity_associations, -> { preload(:timelogs, :assignees, :author, :notes, :labels, project: [:route, { namespace: :route }] ) }
scope :with_label_attributes, ->(label_attributes) { joins(:labels).where(labels: label_attributes) } scope :with_label_attributes, ->(label_attributes) { joins(:labels).where(labels: label_attributes) }
scope :with_alert_management_alerts, -> { joins(:alert_management_alert) } scope :with_alert_management_alerts, -> { joins(:alert_management_alert) }
scope :with_prometheus_alert_events, -> { joins(:issues_prometheus_alert_events) } scope :with_prometheus_alert_events, -> { joins(:issues_prometheus_alert_events) }
scope :with_self_managed_prometheus_alert_events, -> { joins(:issues_self_managed_prometheus_alert_events) } scope :with_self_managed_prometheus_alert_events, -> { joins(:issues_self_managed_prometheus_alert_events) }
scope :with_api_entity_associations, -> {
preload(:timelogs, :closed_by, :assignees, :author, :notes, :labels,
milestone: { project: [:route, { namespace: :route }] },
project: [:route, { namespace: :route }])
}
scope :public_only, -> { where(confidential: false) } scope :public_only, -> { where(confidential: false) }
scope :confidential_only, -> { where(confidential: true) } scope :confidential_only, -> { where(confidential: true) }
......
---
title: Fix N+1 for project/:id/issues API endpoint
merge_request: 37508
author:
type: performance
...@@ -180,12 +180,15 @@ RSpec.describe API::Issues do ...@@ -180,12 +180,15 @@ RSpec.describe API::Issues do
it 'avoids N+1 queries' do it 'avoids N+1 queries' do
get api("/projects/#{project.id}/issues", user) get api("/projects/#{project.id}/issues", user)
create_list(:issue, 3, project: project) create_list(:issue, 3, project: project, closed_by: user)
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
get api("/projects/#{project.id}/issues", user) get api("/projects/#{project.id}/issues", user)
end.count end.count
milestone = create(:milestone, project: project)
create(:issue, project: project, milestone: milestone, closed_by: create(:user))
expect do expect do
get api("/projects/#{project.id}/issues", user) get api("/projects/#{project.id}/issues", user)
end.not_to exceed_all_query_limit(control_count) end.not_to exceed_all_query_limit(control_count)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment