From 53801b1206ff9e165b30117e3c3bcf543db7ad2c Mon Sep 17 00:00:00 2001 From: Andreas Brandl Date: Tue, 27 Aug 2019 19:15:28 +0200 Subject: Preload routes information This fixes a high frequency N+1 issue: `RoutableActions#find_routable!` is used across many controllers to retrieve e.g. the Project or Namespace by path. The `#find_routable!` method calls `#ensure_canonical_path` which in turn retrieves `#full_path` from the given Routable. This in turn triggers a lookup on `routes`, leading to a high frequency of these queries: ```sql SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT $3 ``` This is unnecessary as we already join `routes` in `Routable#find_by_full_path` anyways. --- spec/models/concerns/routable_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'spec') diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb index cff86afe768..cad705ee594 100644 --- a/spec/models/concerns/routable_spec.rb +++ b/spec/models/concerns/routable_spec.rb @@ -66,6 +66,13 @@ describe Group, 'Routable' do it { expect(described_class.find_by_full_path(group.to_param.upcase)).to eq(group) } it { expect(described_class.find_by_full_path(nested_group.to_param)).to eq(nested_group) } it { expect(described_class.find_by_full_path('unknown')).to eq(nil) } + + it 'includes route information when loading a record' do + path = group.to_param + control_count = ActiveRecord::QueryRecorder.new { described_class.find_by_full_path(path) }.count + + expect { described_class.find_by_full_path(path).route }.not_to exceed_all_query_limit(control_count) + end end context 'with redirect routes' do -- cgit v1.2.1