Commit d69f9af7 authored by Thong Kuah's avatar Thong Kuah

Merge branch '63212-n-1-queries-in-projects-id-boards-api' into 'master'

Remove N+1 queries in boards API

See merge request gitlab-org/gitlab-ce!29634
parents b0845b62 04d2d8f9
......@@ -4,11 +4,14 @@ class Board < ApplicationRecord
belongs_to :group
belongs_to :project
has_many :lists, -> { order(:list_type, :position) }, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
has_many :lists, -> { ordered }, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
has_many :destroyable_lists, -> { destroyable.ordered }, class_name: "List"
validates :project, presence: true, if: :project_needed?
validates :group, presence: true, unless: :project
scope :with_associations, -> { preload(:destroyable_lists) }
def project_needed?
!group
end
......
......@@ -16,6 +16,7 @@ class List < ApplicationRecord
scope :destroyable, -> { where(list_type: list_types.slice(*destroyable_types).values) }
scope :movable, -> { where(list_type: list_types.slice(*movable_types).values) }
scope :preload_associations, -> { preload(:board, :label) }
scope :ordered, -> { order(:list_type, :position) }
class << self
def destroyable_types
......
......@@ -27,7 +27,7 @@ module API
end
get '/' do
authorize!(:read_board, user_project)
present paginate(board_parent.boards), with: Entities::Board
present paginate(board_parent.boards.with_associations), with: Entities::Board
end
desc 'Find a project board' do
......
......@@ -11,7 +11,7 @@ module API
end
def board_lists
board.lists.destroyable
board.destroyable_lists
end
def create_list
......
......@@ -1101,7 +1101,7 @@ module API
expose :project, using: Entities::BasicProjectDetails
expose :lists, using: Entities::List do |board|
board.lists.destroyable
board.destroyable_lists
end
end
......
......@@ -37,7 +37,7 @@ module API
use :pagination
end
get '/' do
present paginate(board_parent.boards), with: Entities::Board
present paginate(board_parent.boards.with_associations), with: Entities::Board
end
end
......
......@@ -14,6 +14,16 @@ shared_examples_for 'group and project boards' do |route_definition, ee = false|
end
end
it 'avoids N+1 queries' do
pat = create(:personal_access_token, user: user)
control = ActiveRecord::QueryRecorder.new { get api(root_url, personal_access_token: pat) }
create(:milestone, "#{board_parent.class.name.underscore}": board_parent)
create(:board, "#{board_parent.class.name.underscore}": board_parent)
expect { get api(root_url, personal_access_token: pat) }.not_to exceed_query_limit(control)
end
describe "GET #{route_definition}" do
context "when unauthenticated" do
it "returns authentication error" do
......
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