PERF: Eager load linkables when loading custom sidebar sections (#20490)
Not eager loading was resulting in the N+1 queries problem when serializing with the `CurrentUserSerializer` as `CurrentUserSerializer#sidebar_sections` serializes the sections with `SidebarSectionSerializer` which fetches all the `SidebarUrl` records for each `SidebarSection` record.
This commit is contained in:
parent
24188beaaf
commit
8fec1a412b
|
@ -79,6 +79,7 @@ class CurrentUserSerializer < BasicUserSerializer
|
|||
|
||||
def sidebar_sections
|
||||
SidebarSection
|
||||
.includes(sidebar_section_links: :linkable)
|
||||
.where("public OR user_id = ?", object.id)
|
||||
.order("(public IS TRUE) DESC")
|
||||
.map { |section| SidebarSectionSerializer.new(section, root: false) }
|
||||
|
|
|
@ -7,3 +7,8 @@ Fabricator(:category_sidebar_section_link, from: :sidebar_section_link) do
|
|||
end
|
||||
|
||||
Fabricator(:tag_sidebar_section_link, from: :sidebar_section_link) { linkable(fabricator: :tag) }
|
||||
|
||||
Fabricator(:custom_sidebar_section_link, from: :sidebar_section_link) do
|
||||
linkable(fabricator: :sidebar_url)
|
||||
sidebar_section(fabricator: :sidebar_section)
|
||||
end
|
||||
|
|
|
@ -297,4 +297,53 @@ RSpec.describe CurrentUserSerializer do
|
|||
end
|
||||
|
||||
include_examples "User Sidebar Serializer Attributes", described_class
|
||||
|
||||
describe "#sidebar_sections" do
|
||||
fab!(:group) { Fabricate(:group) }
|
||||
fab!(:sidebar_section) { Fabricate(:sidebar_section, user: user) }
|
||||
|
||||
before do
|
||||
group.add(user)
|
||||
SiteSetting.enable_custom_sidebar_sections = group.id
|
||||
end
|
||||
|
||||
it "eager loads sidebar_urls" do
|
||||
custom_sidebar_section_link_1 =
|
||||
Fabricate(:custom_sidebar_section_link, user: user, sidebar_section: sidebar_section)
|
||||
|
||||
# warmup
|
||||
described_class.new(user, scope: Guardian.new(user), root: false).as_json
|
||||
|
||||
initial_count =
|
||||
track_sql_queries do
|
||||
serialized = described_class.new(user, scope: Guardian.new(user), root: false).as_json
|
||||
|
||||
expect(serialized[:sidebar_sections].map { |sidebar_section| sidebar_section.id }).to eq(
|
||||
[sidebar_section.id],
|
||||
)
|
||||
|
||||
expect(serialized[:sidebar_sections].first.links.map { |link| link.id }).to eq(
|
||||
[custom_sidebar_section_link_1.linkable.id],
|
||||
)
|
||||
end.count
|
||||
|
||||
custom_sidebar_section_link_2 =
|
||||
Fabricate(:custom_sidebar_section_link, user: user, sidebar_section: sidebar_section)
|
||||
|
||||
final_count =
|
||||
track_sql_queries do
|
||||
serialized = described_class.new(user, scope: Guardian.new(user), root: false).as_json
|
||||
|
||||
expect(serialized[:sidebar_sections].map { |sidebar_section| sidebar_section.id }).to eq(
|
||||
[sidebar_section.id],
|
||||
)
|
||||
|
||||
expect(serialized[:sidebar_sections].first.links.map { |link| link.id }).to eq(
|
||||
[custom_sidebar_section_link_1.linkable.id, custom_sidebar_section_link_2.linkable.id],
|
||||
)
|
||||
end.count
|
||||
|
||||
expect(initial_count).to eq(final_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue