Skip to content

Commit 770ee2d

Browse files
committed
performance: Update page tree eager loading
We need to include the locker during page tree eager loading in order to prevent N+1 queries for trees with locked pages.
1 parent f84b5e3 commit 770ee2d

3 files changed

Lines changed: 39 additions & 5 deletions

File tree

app/controllers/alchemy/admin/pages_controller.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ def index
6262
elsif @current_language.root_page
6363
@root_page = Alchemy::PageTreePreloader.new(
6464
page: @current_language.root_page,
65-
user: current_alchemy_user
65+
user: current_alchemy_user,
66+
admin_includes: true
6667
).call
6768
end
6869
end
@@ -173,7 +174,11 @@ def fold
173174
respond_to do |format|
174175
format.turbo_stream do
175176
if was_folded
176-
@page = PageTreePreloader.new(page: @page, user: current_alchemy_user).call
177+
@page = PageTreePreloader.new(
178+
page: @page,
179+
user: current_alchemy_user,
180+
admin_includes: true
181+
).call
177182
else
178183
head 200
179184
end

app/services/alchemy/page_tree_preloader.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ module Alchemy
1313
class PageTreePreloader
1414
# @param page [Page] Starting page for loading descendants
1515
# @param user [User, nil] User for folding support
16-
def initialize(page:, user: nil)
16+
# @param admin_includes [Boolean] Whether to include admin-only associations like :locker
17+
def initialize(page:, user: nil, admin_includes: false)
1718
@page = page
1819
@user = user
20+
@admin_includes = admin_includes
1921
end
2022

2123
# Preloads and returns the page tree
@@ -43,7 +45,7 @@ def call
4345

4446
private
4547

46-
attr_reader :page, :user
48+
attr_reader :page, :user, :admin_includes
4749

4850
# Load folded page IDs for the user
4951
def load_folded_page_ids
@@ -83,7 +85,16 @@ def preload_children_associations(pages, folded_page_ids: Set.new)
8385

8486
# Associations to preload for sitemap rendering
8587
def preload_associations
86-
[:public_version, {language: {site: :languages}}]
88+
associations = [
89+
{
90+
language: {
91+
site: :languages
92+
}
93+
},
94+
:public_version
95+
]
96+
associations.push(:locker) if admin_includes
97+
associations
8798
end
8899
end
89100

spec/services/alchemy/page_tree_preloader_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
expect(subject.language.association(:site)).to be_loaded
4040
end
4141

42+
it "does not preload locker association" do
43+
expect(subject.association(:locker)).not_to be_loaded
44+
end
45+
4246
context "with folded pages" do
4347
before do
4448
child_page_1.fold!(user.id, true)
@@ -60,5 +64,19 @@
6064
expect(subject.children.first.children).to eq([grandchild_page])
6165
end
6266
end
67+
68+
context "with admin_includes: true" do
69+
subject do
70+
described_class.new(
71+
page: root_page.reload,
72+
user: user,
73+
admin_includes: true
74+
).call
75+
end
76+
77+
it "preloads locker association" do
78+
expect(subject.association(:locker)).to be_loaded
79+
end
80+
end
6381
end
6482
end

0 commit comments

Comments
 (0)