Skip to content
Snippets Groups Projects
Commit 426f1c20 authored by Charlie Ablett's avatar Charlie Ablett
Browse files

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
parent 4633df7b
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -11,7 +11,7 @@ module API
end
 
def board_lists
board.lists.destroyable
board.destroyable_lists
end
 
def create_list
Loading
Loading
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment