Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit e54f2da

Browse files
authored
FIX: Unnecessary complex preloading accidentally filters some topics. (#945)
The `topic_query_create_list_topics` modifier we append was always meant to avoid an N+1 situation when serializing gists. However, I tried to be too smart and only preload these, which resulted in some topics with *only* regular summaries getting removed from the list. This issue became apparent now we are adding gists to other lists besides hot. Let's simplify the preloading, which still solves the N+1 issue, and let the serializer get the needed summary.
1 parent 1921e4e commit e54f2da

File tree

2 files changed

+41
-21
lines changed

2 files changed

+41
-21
lines changed

lib/summarization/entry_point.rb

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,14 @@ def inject_into(plugin)
1717
scope.can_see_summary?(object.topic)
1818
end
1919

20-
# plugin.register_modifier(:topic_query_create_list_topics) do |topics, options|
21-
# if Discourse.filters.include?(options[:filter]) && SiteSetting.ai_summarization_enabled &&
22-
# SiteSetting.ai_summarize_max_hot_topics_gists_per_batch > 0
23-
# topics
24-
# .includes(:ai_summaries)
25-
# .where(
26-
# "ai_summaries.id IS NULL OR ai_summaries.summary_type = ?",
27-
# AiSummary.summary_types[:gist],
28-
# )
29-
# .references(:ai_summaries)
30-
# else
31-
# topics
32-
# end
33-
# end
20+
plugin.register_modifier(:topic_query_create_list_topics) do |topics, options|
21+
if Discourse.filters.include?(options[:filter]) && SiteSetting.ai_summarization_enabled &&
22+
SiteSetting.ai_summarize_max_hot_topics_gists_per_batch > 0
23+
topics.includes(:ai_summaries)
24+
else
25+
topics
26+
end
27+
end
3428

3529
plugin.add_to_serializer(
3630
:topic_list_item,

spec/lib/modules/summarization/entry_point_spec.rb

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,37 @@
44
before do
55
assign_fake_provider_to(:ai_summarization_model)
66
SiteSetting.ai_summarization_enabled = true
7+
SiteSetting.ai_summarize_max_hot_topics_gists_per_batch = 100
78
end
89

910
fab!(:user)
1011

1112
describe "#inject_into" do
1213
describe "hot topics gist summarization" do
1314
fab!(:topic_ai_gist)
14-
fab!(:regular_summary) { Fabricate(:ai_summary, target: topic_ai_gist.target) }
1515

1616
before { TopicHotScore.create!(topic_id: topic_ai_gist.target_id, score: 1.0) }
1717

1818
let(:topic_query) { TopicQuery.new(user) }
1919

2020
describe "topic_query_create_list_topics modifier" do
2121
context "when hot topic summarization is enabled" do
22-
before { SiteSetting.ai_summarize_max_hot_topics_gists_per_batch = 100 }
22+
it "doesn't duplicate records when there more than one summary type" do
23+
Fabricate(:ai_summary, target: topic_ai_gist.target)
2324

24-
skip "preloads only gist summaries" do
25-
gist_topic = topic_query.list_hot.topics.find { |t| t.id == topic_ai_gist.target_id }
25+
expect(topic_query.list_hot.topics.map(&:id)).to contain_exactly(
26+
topic_ai_gist.target_id,
27+
)
28+
end
2629

27-
expect(gist_topic.ai_summaries.size).to eq(1)
28-
expect(gist_topic.ai_summaries.first).to eq(topic_ai_gist)
30+
it "doesn't exclude records when the topic has a single different summary" do
31+
regular_summary_2 = Fabricate(:ai_summary)
32+
TopicHotScore.create!(topic_id: regular_summary_2.target_id, score: 1.0)
33+
34+
expect(topic_query.list_hot.topics.map(&:id)).to contain_exactly(
35+
regular_summary_2.target_id,
36+
topic_ai_gist.target_id,
37+
)
2938
end
3039

3140
it "doesn't filter out hot topics without summaries" do
@@ -118,11 +127,28 @@
118127
gist_topic,
119128
scope: Guardian.new(admin),
120129
root: false,
121-
filter: :hot,
130+
filter: :unread,
122131
).as_json
123132

124133
expect(serialized[:ai_topic_gist]).to be_present
125134
end
135+
136+
it "doesn't include the summary if it's not a gist" do
137+
regular_summary_2 = Fabricate(:ai_summary)
138+
TopicHotScore.create!(topic_id: regular_summary_2.target_id, score: 1.0)
139+
140+
hot_topic = topic_query.list_hot.topics.find { |t| t.id == regular_summary_2.target_id }
141+
142+
serialized =
143+
TopicListItemSerializer.new(
144+
hot_topic,
145+
scope: Guardian.new(user),
146+
root: false,
147+
filter: :hot,
148+
).as_json
149+
150+
expect(serialized[:ai_topic_gist]).to be_nil
151+
end
126152
end
127153
end
128154
end

0 commit comments

Comments
 (0)