Skip to content

Commit 06c45b5

Browse files
committed
Prevent n+1 when loading topic post's translation metadata
1 parent e45e0b3 commit 06c45b5

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# frozen_string_literal: true
2+
3+
module DiscourseTranslator
4+
module TopicViewSerializerExtension
5+
def posts
6+
if SiteSetting.translator_enabled?
7+
object.instance_variable_set(:@posts, object.posts.includes(:content_locale))
8+
end
9+
super
10+
end
11+
end
12+
end

plugin.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module ::DiscourseTranslator
3131
Guardian.prepend(DiscourseTranslator::GuardianExtension)
3232
Post.prepend(DiscourseTranslator::PostExtension)
3333
Topic.prepend(DiscourseTranslator::TopicExtension)
34+
TopicViewSerializer.prepend(DiscourseTranslator::TopicViewSerializerExtension)
3435
end
3536

3637
on(:post_process_cooked) do |_, post|
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# frozen_string_literal: true
2+
3+
require "rails_helper"
4+
5+
describe TopicViewSerializer do
6+
fab!(:user)
7+
fab!(:topic)
8+
fab!(:post1) { Fabricate(:post, topic: topic).set_detected_locale("en") }
9+
fab!(:post2) { Fabricate(:post, topic: topic).set_detected_locale("es") }
10+
fab!(:post3) { Fabricate(:post, topic: topic).set_detected_locale("ja") }
11+
12+
before do
13+
SiteSetting.translator_enabled = true
14+
SiteSetting.restrict_translation_by_group = "#{Group::AUTO_GROUPS[:everyone]}"
15+
SiteSetting.restrict_translation_by_poster_group = "#{Group::AUTO_GROUPS[:everyone]}"
16+
end
17+
18+
it "preloads translations without N+1 queries" do
19+
topic_view = TopicView.new(topic)
20+
serializer = TopicViewSerializer.new(topic_view, scope: Guardian.new(user), root: false)
21+
22+
# ensure translation data is included in the JSON
23+
json = {}
24+
queries = track_sql_queries { json = serializer.as_json }
25+
posts_json = json[:post_stream][:posts]
26+
expect(posts_json.map { |p| p[:can_translate] }).to eq([false, true, true])
27+
28+
translation_queries = queries.count { |q| q.include?("discourse_translator_post_locales") }
29+
expect(translation_queries).to eq(1) # would be 3 (posts) if not preloaded
30+
31+
expect(topic_view.posts.first.association(:content_locale)).to be_loaded
32+
end
33+
end

0 commit comments

Comments
 (0)