Preload project features in reference parser

Preloading of project_features mitigates N+1 queries when checking
references in other projects.

When loading projects for resources referenced in comments it
makes sense to include also associated project_features because
in the following step (`can_read_reference?(user, projects[node],
node)`) project features is used for checking permissions for the given
project.
This commit is contained in:
Jan Provaznik 2018-09-30 19:54:21 +02:00
parent 227cc997fb
commit 7f4452d406
4 changed files with 29 additions and 2 deletions

View file

@ -0,0 +1,5 @@
---
title: Mitigate N+1 queries when parsing commit references in comments.
merge_request:
author:
type: performance

View file

@ -215,7 +215,7 @@ module Banzai
#
def projects_for_nodes(nodes)
@projects_for_nodes ||=
grouped_objects_for_nodes(nodes, Project, 'data-project')
grouped_objects_for_nodes(nodes, Project.includes(:project_feature), 'data-project')
end
def can?(user, permission, subject = :global)

View file

@ -120,4 +120,22 @@ describe Banzai::ReferenceParser::CommitParser do
expect(subject.find_commits(project, %w{123})).to eq([])
end
end
context 'when checking commits on another projects' do
let(:control_links) do
[commit_link]
end
let(:actual_links) do
control_links + [commit_link, commit_link]
end
def commit_link
project = create(:project, :repository, :public)
Nokogiri::HTML.fragment(%Q{<a data-commit="#{project.commit.id}" data-project="#{project.id}"></a>}).children[0]
end
it_behaves_like 'no project N+1 queries'
end
end

View file

@ -3,7 +3,7 @@ module ReferenceParserHelpers
Nokogiri::HTML.fragment('<a></a>').children[0]
end
shared_examples 'no N+1 queries' do
shared_examples 'no project N+1 queries' do
it 'avoids N+1 queries in #nodes_visible_to_user', :request_store do
context = Banzai::RenderContext.new(project, user)
@ -19,6 +19,10 @@ module ReferenceParserHelpers
expect(actual.count).to be <= control.count
expect(actual.cached_count).to be <= control.cached_count
end
end
shared_examples 'no N+1 queries' do
it_behaves_like 'no project N+1 queries'
it 'avoids N+1 queries in #records_for_nodes', :request_store do
context = Banzai::RenderContext.new(project, user)