diff --git a/lib/bookmark_query.rb b/lib/bookmark_query.rb index 44ab7b257fe..d38bdabf7c6 100644 --- a/lib/bookmark_query.rb +++ b/lib/bookmark_query.rb @@ -5,6 +5,19 @@ # in the user/activity/bookmarks page. class BookmarkQuery + cattr_accessor :preloaded_custom_fields + self.preloaded_custom_fields = Set.new + + def self.on_preload(&blk) + (@preload ||= Set.new) << blk + end + + def self.preload(bookmarks, object) + if @preload + @preload.each { |preload| preload.call(bookmarks, object) } + end + end + def initialize(user, params = {}) @user = user @params = params @@ -15,18 +28,28 @@ class BookmarkQuery .joins('INNER JOIN topics ON topics.id = bookmarks.topic_id') .joins('INNER JOIN posts ON posts.id = bookmarks.post_id') .joins('INNER JOIN users ON users.id = posts.user_id') - .order('created_at DESC') + .order('bookmarks.created_at DESC') if @params[:limit] results = results.limit(@params[:limit]) end + if BookmarkQuery.preloaded_custom_fields.any? + Topic.preload_custom_fields( + results.map(&:topic), BookmarkQuery.preloaded_custom_fields + ) + end + + BookmarkQuery.preload(results, self) + results end private def user_bookmarks - Bookmark.where(user: @user).includes(:topic).includes(post: :user) + Bookmark.where(user: @user) + .includes(topic: :tags) + .includes(post: :user) end end diff --git a/spec/lib/bookmark_query_spec.rb b/spec/lib/bookmark_query_spec.rb new file mode 100644 index 00000000000..2fe99c38930 --- /dev/null +++ b/spec/lib/bookmark_query_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe BookmarkQuery do + fab!(:user) { Fabricate(:user) } + fab!(:bookmark1) { Fabricate(:bookmark, user: user) } + fab!(:bookmark2) { Fabricate(:bookmark, user: user) } + let(:params) { {} } + + subject { described_class.new(user, params) } + + describe "#list_all" do + it "returns all the bookmarks for a user" do + expect(subject.list_all.count).to eq(2) + end + + it "runs the on_preload block provided passing in bookmarks" do + preloaded_bookmarks = [] + BookmarkQuery.on_preload do |bookmarks, bq| + (preloaded_bookmarks << bookmarks).flatten + end + subject.list_all + expect(preloaded_bookmarks.any?).to eq(true) + end + + context "when the limit param is provided" do + let(:params) { { limit: 1 } } + it "is respected" do + expect(subject.list_all.count).to eq(1) + end + end + + context "when there are topic custom fields to preload" do + before do + TopicCustomField.create( + topic_id: bookmark1.topic.id, name: 'test_field', value: 'test' + ) + BookmarkQuery.preloaded_custom_fields << "test_field" + end + it "preloads them" do + Topic.expects(:preload_custom_fields) + expect( + subject.list_all.find do |b| + b.topic_id = bookmark1.topic_id + end.topic.custom_fields['test_field'] + ).not_to eq(nil) + end + end + end +end