Commit 07aa4bcf authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch 'sh-optimize-todos-controller' into 'master'

Eliminate N+1 queries in Dashboard::TodosController

Closes #43042

See merge request gitlab-org/gitlab-ce!29954
parents 2b327c1b f2d93226
...@@ -10,6 +10,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController ...@@ -10,6 +10,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
def index def index
@sort = params[:sort] @sort = params[:sort]
@todos = @todos.page(params[:page]) @todos = @todos.page(params[:page])
@todos = @todos.with_entity_associations
return if redirect_out_of_range(@todos) return if redirect_out_of_range(@todos)
end end
......
...@@ -170,7 +170,7 @@ module TodosHelper ...@@ -170,7 +170,7 @@ module TodosHelper
end end
def todo_group_options def todo_group_options
groups = current_user.authorized_groups.map do |group| groups = current_user.authorized_groups.with_route.map do |group|
{ id: group.id, text: group.full_name } { id: group.id, text: group.full_name }
end end
......
...@@ -60,7 +60,7 @@ class Todo < ApplicationRecord ...@@ -60,7 +60,7 @@ class Todo < ApplicationRecord
scope :for_type, -> (type) { where(target_type: type) } scope :for_type, -> (type) { where(target_type: type) }
scope :for_target, -> (id) { where(target_id: id) } scope :for_target, -> (id) { where(target_id: id) }
scope :for_commit, -> (id) { where(commit_id: id) } scope :for_commit, -> (id) { where(commit_id: id) }
scope :with_api_entity_associations, -> { preload(:target, :author, :note, group: :route, project: [:route, { namespace: :route }]) } scope :with_entity_associations, -> { preload(:target, :author, :note, group: :route, project: [:route, { namespace: :route }]) }
scope :joins_issue_and_assignees, -> { left_joins(issue: :assignees) } scope :joins_issue_and_assignees, -> { left_joins(issue: :assignees) }
state_machine :state, initial: :pending do state_machine :state, initial: :pending do
......
---
title: Eliminate N+1 queries in Dashboard::TodosController
merge_request: 29954
author:
type: performance
...@@ -77,7 +77,7 @@ module API ...@@ -77,7 +77,7 @@ module API
use :pagination use :pagination
end end
get do get do
todos = paginate(find_todos.with_api_entity_associations) todos = paginate(find_todos.with_entity_associations)
options = { with: Entities::Todo, current_user: current_user } options = { with: Entities::Todo, current_user: current_user }
batch_load_issuable_metadata(todos, options) batch_load_issuable_metadata(todos, options)
......
...@@ -44,6 +44,34 @@ describe Dashboard::TodosController do ...@@ -44,6 +44,34 @@ describe Dashboard::TodosController do
end end
end end
context "with render_views" do
render_views
it 'avoids N+1 queries', :request_store do
merge_request = create(:merge_request, source_project: project)
create(:todo, project: project, author: author, user: user, target: merge_request)
create(:issue, project: project, assignees: [user])
group = create(:group)
group.add_owner(user)
get :index
control = ActiveRecord::QueryRecorder.new { get :index }
create(:issue, project: project, assignees: [user])
group_2 = create(:group)
group_2.add_owner(user)
project_2 = create(:project)
project_2.add_developer(user)
merge_request_2 = create(:merge_request, source_project: project_2)
create(:todo, project: project, author: author, user: user, target: merge_request_2)
expect { get :index }.not_to exceed_query_limit(control)
expect(response.status).to eq(200)
end
end
context 'group authorization' do context 'group authorization' do
it 'renders 404 when user does not have read access on given group' do it 'renders 404 when user does not have read access on given group' do
unauthorized_group = create(:group, :private) unauthorized_group = create(:group, :private)
......
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