From a0edaa9210642f23ef3ea4984c6d6f77cbbba878 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 23 Apr 2017 22:32:50 -0700 Subject: Cache Routable#full_path in RequestStore to reduce duplicate route loads We see in #27387 that a call to `polymorphic_path` will cause duplicate SELECT route calls for each merge request in a milestone. This happens because calling `project.namespace.becomes(Namespace)` will instantiate a new instance of a Namespace for each merge request, which causes a N+1 query on the routes table. This change caches the state of the route by the specific class and ID, which dramatically eliminates duplicate work. --- spec/models/concerns/routable_spec.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'spec/models') diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb index f191605dbdb..221647d7a48 100644 --- a/spec/models/concerns/routable_spec.rb +++ b/spec/models/concerns/routable_spec.rb @@ -194,6 +194,24 @@ describe Group, 'Routable' do it { expect(group.full_path).to eq(group.path) } it { expect(nested_group.full_path).to eq("#{group.full_path}/#{nested_group.path}") } + + context 'with RequestStore active' do + before do + RequestStore.begin! + end + + after do + RequestStore.end! + RequestStore.clear! + end + + it 'does not load the route table more than once' do + expect(group).to receive(:uncached_full_path).once.and_call_original + + 3.times { group.full_path } + expect(group.full_path).to eq(group.path) + end + end end describe '#full_name' do -- cgit v1.2.1