summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChantal Rollison <crollison@gitlab.com>2018-09-10 10:26:33 -0700
committerChantal Rollison <crollison@gitlab.com>2018-10-05 07:38:37 -0700
commitd6f28eaee41418561ae012d58535312a6de4ab91 (patch)
tree0efa4ec8d0eb8e5c3e9390dbd8755505bc224643
parent8a8ae2f57fe0db9b33f100e9a68c9eac4fd71c4d (diff)
downloadgitlab-ce-ccr/43034_issues_controller_100_queries.tar.gz
Add preload in issues controllerccr/43034_issues_controller_100_queries
-rw-r--r--app/controllers/boards/issues_controller.rb14
-rw-r--r--app/models/board.rb4
-rw-r--r--app/services/boards/lists/list_service.rb4
-rw-r--r--changelogs/unreleased/ccr-43034_issues_controller_100_queries.yml5
-rw-r--r--spec/controllers/boards/issues_controller_spec.rb47
5 files changed, 65 insertions, 9 deletions
diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb
index 4f3d737e3ce..55e2b49d003 100644
--- a/app/controllers/boards/issues_controller.rb
+++ b/app/controllers/boards/issues_controller.rb
@@ -18,14 +18,18 @@ module Boards
list_service = Boards::Issues::ListService.new(board_parent, current_user, filter_params)
issues = list_service.execute
issues = issues.page(params[:page]).per(params[:per] || 20).without_count
- make_sure_position_is_set(issues) if Gitlab::Database.read_write?
- issues = issues.preload(:project,
- :milestone,
+ make_sure_position_is_set(issues)
+ issues = issues.preload(:milestone,
:assignees,
+ project: [
+ :route,
+ {
+ namespace: [:route]
+ }
+ ],
labels: [:priorities],
notes: [:award_emoji, :author]
)
-
render_issues(issues, list_service.metadata)
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -61,6 +65,8 @@ module Boards
end
def make_sure_position_is_set(issues)
+ return unless Gitlab::Database.read_write?
+
issues.each do |issue|
issue.move_to_end && issue.save unless issue.relative_position
end
diff --git a/app/models/board.rb b/app/models/board.rb
index a137863456c..b060bc42618 100644
--- a/app/models/board.rb
+++ b/app/models/board.rb
@@ -32,4 +32,8 @@ class Board < ActiveRecord::Base
def scoped?
false
end
+
+ def self.preload_label_and_board(lists)
+ lists.preload(:label, :board)
+ end
end
diff --git a/app/services/boards/lists/list_service.rb b/app/services/boards/lists/list_service.rb
index e10eb52e041..001d42ed6c6 100644
--- a/app/services/boards/lists/list_service.rb
+++ b/app/services/boards/lists/list_service.rb
@@ -6,7 +6,9 @@ module Boards
def execute(board)
board.lists.create(list_type: :backlog) unless board.lists.backlog.exists?
- board.lists
+ lists = board.lists
+
+ Board.preload_label_and_board(lists)
end
end
end
diff --git a/changelogs/unreleased/ccr-43034_issues_controller_100_queries.yml b/changelogs/unreleased/ccr-43034_issues_controller_100_queries.yml
new file mode 100644
index 00000000000..d92c0e74c07
--- /dev/null
+++ b/changelogs/unreleased/ccr-43034_issues_controller_100_queries.yml
@@ -0,0 +1,5 @@
+---
+title: Add preload for routes and namespaces for issues controller.
+merge_request: 21651
+author:
+type: performance
diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb
index d98e6ff0df8..a859290c228 100644
--- a/spec/controllers/boards/issues_controller_spec.rb
+++ b/spec/controllers/boards/issues_controller_spec.rb
@@ -3,6 +3,9 @@ require 'spec_helper'
describe Boards::IssuesController do
let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
+ let(:group) { create(:group, :private, projects: [project]) }
+ let(:group_board) { create(:board, group: group) }
+ let(:sub_group_1) { create(:group, :private, parent: group) }
let(:user) { create(:user) }
let(:guest) { create(:user) }
@@ -11,9 +14,11 @@ describe Boards::IssuesController do
let!(:list1) { create(:list, board: board, label: planning, position: 0) }
let!(:list2) { create(:list, board: board, label: development, position: 1) }
+ let!(:list3) { create(:list, board: group_board, label: development, position: 2) }
before do
project.add_maintainer(user)
+ group.add_maintainer(user)
project.add_guest(guest)
end
@@ -56,6 +61,37 @@ describe Boards::IssuesController do
expect { list_issues(user: user, board: board, list: list2) }.not_to exceed_query_limit(control_count)
end
+
+ it 'avoids N+1 database queries when adding a project', :request_store do
+ create(:labeled_issue, project: project, labels: [development])
+ control_count = ActiveRecord::QueryRecorder.new { list_issues(user: user, board: group_board, list: list3) }.count
+
+ 2.times do
+ p = create(:project, group: group)
+ create(:labeled_issue, project: p, labels: [development])
+ end
+
+ project_2 = create(:project, group: group)
+ create(:labeled_issue, project: project_2, labels: [development], assignees: [johndoe])
+
+ expect { list_issues(user: user, board: group_board, list: list3) }.not_to exceed_query_limit(control_count)
+ end
+
+ it 'avoids N+1 database queries when adding a subgroup, project, and issue', :nested_groups do
+ create(:project, group: sub_group_1)
+ create(:labeled_issue, project: project, labels: [development])
+ control_count = ActiveRecord::QueryRecorder.new { list_issues(user: user, board: group_board, list: list3) }.count
+ project_2 = create(:project, group: group)
+
+ 2.times do
+ p = create(:project, group: sub_group_1)
+ create(:labeled_issue, project: p, labels: [development])
+ end
+
+ create(:labeled_issue, project: project_2, labels: [development], assignees: [johndoe])
+
+ expect { list_issues(user: user, board: group_board, list: list3) }.not_to exceed_query_limit(control_count)
+ end
end
context 'with invalid list id' do
@@ -102,12 +138,15 @@ describe Boards::IssuesController do
sign_in(user)
params = {
- namespace_id: project.namespace.to_param,
- project_id: project,
- board_id: board.to_param,
- list_id: list.try(:to_param)
+ board_id: board.to_param,
+ list_id: list.try(:to_param)
}
+ unless board.try(:parent)&.is_a?(Group)
+ params[:namespace_id] = project.namespace.to_param
+ params[:project_id] = project
+ end
+
get :index, params.compact
end
end