提交 426f1c20 编写于 作者: C charlieablett

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
上级 4633df7b
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册