PERF: Load topic bookmarks for the user in user_post_bookmarks (#10197)

PERF: Load topic bookmarks for the user in user_post_bookmarks (#10197)

Instead of loading all of the user bookmarks using all the post IDs in a topic, load all the bookmarks for a user using the topic ID. This eliminates a costly WHERE ID IN query.

diff --git a/lib/topic_view.rb b/lib/topic_view.rb
index bea37c1..aa0c46a 100644
--- a/lib/topic_view.rb
+++ b/lib/topic_view.rb
@@ -435,7 +435,7 @@ class TopicView
   end
 
   def user_post_bookmarks
-    @user_post_bookmarks ||= Bookmark.where(user: @user, post_id: unfiltered_post_ids)
+    @user_post_bookmarks ||= @topic.bookmarks.where(user: @user)
   end
 
   def reviewable_counts
diff --git a/spec/components/topic_view_spec.rb b/spec/components/topic_view_spec.rb
index 31dcd75..624e9a3 100644
--- a/spec/components/topic_view_spec.rb
+++ b/spec/components/topic_view_spec.rb
@@ -334,6 +334,19 @@ describe TopicView do
       end
     end
 
+    context "#user_post_bookmarks" do
+      let!(:user) { Fabricate(:user) }
+      let!(:bookmark1) { Fabricate(:bookmark, post: Fabricate(:post, topic: topic), user: user) }
+      let!(:bookmark2) { Fabricate(:bookmark, post: Fabricate(:post, topic: topic), user: user) }
+      let!(:bookmark3) { Fabricate(:bookmark, post: Fabricate(:post, topic: topic)) }
+
+      it "returns all the bookmarks in the topic for a user" do
+        expect(TopicView.new(topic.id, user).user_post_bookmarks.pluck(:id)).to match_array(
+          [bookmark1.id, bookmark2.id]
+        )
+      end
+    end
+
     context '.topic_user' do
       it 'returns nil when there is no user' do
         expect(TopicView.new(topic.id, nil).topic_user).to be_blank

GitHub sha: e0713455

1 Like

This commit appears in #10197 which was merged by martin.