Remove N+1 query for project and group boards
- Add test for N+1 queries - Add destroyable lists scope to Board and List - Preload lists for both project and group boards
This commit is contained in:
parent
4633df7b9e
commit
426f1c20b1
7 changed files with 25 additions and 4 deletions
|
@ -5,10 +5,13 @@ class Board < ApplicationRecord
|
|||
belongs_to :project
|
||||
|
||||
has_many :lists, -> { order(:list_type, :position) }, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :destroyable_lists, -> { destroyable }, 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
|
||||
|
|
|
@ -2,4 +2,12 @@
|
|||
|
||||
class BoardSerializer < BaseSerializer
|
||||
entity BoardSimpleEntity
|
||||
|
||||
def represent(resource, opts = {})
|
||||
if resource.respond_to?(:with_associations)
|
||||
resource = resource.with_associations
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue