From 1a5b02755d6c4d0b4f5107f8e27e0ca943a9ee24 Mon Sep 17 00:00:00 2001 From: Roman Rizzi Date: Fri, 16 Sep 2022 12:08:47 -0300 Subject: [PATCH] FIX: Don't fail because flair_uploads weren't eager loaded (#379) The basic group serializer complains that the flair_upload relation has to be eager loaded when attempting to included assigned groups in search results, which is a consequence of using strict loading during search's preload to avoid N+1. Eager loading the association during this would definitely fix the problem, but is it the right solution? It seems to me that this serializer does too much, when we only need a small number of attributes to display the assigned widget. Instead, this commit adds a lightweight custom serializer which grabs only the essentials for it to work. --- app/serializers/assigned_group_serializer.rb | 13 +++++++ plugin.rb | 12 ++---- spec/requests/search_controller_spec.rb | 40 ++++++++++++++++++++ 3 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 app/serializers/assigned_group_serializer.rb create mode 100644 spec/requests/search_controller_spec.rb diff --git a/app/serializers/assigned_group_serializer.rb b/app/serializers/assigned_group_serializer.rb new file mode 100644 index 0000000..7348dba --- /dev/null +++ b/app/serializers/assigned_group_serializer.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class AssignedGroupSerializer < ApplicationSerializer + attributes :id, :name, :assign_icon, :assign_path + + def assign_icon + "group-plus" + end + + def assign_path + "/g/#{object.name}/assigned/everyone" + end +end diff --git a/plugin.rb b/plugin.rb index 9149eb3..244f339 100644 --- a/plugin.rb +++ b/plugin.rb @@ -624,7 +624,7 @@ after_initialize do end add_to_serializer(:topic_list_item, :assigned_to_group) do - BasicGroupSerializer.new(object.assigned_to, scope: scope, root: false).as_json + AssignedGroupSerializer.new(object.assigned_to, scope: scope, root: false).as_json end add_to_serializer(:topic_list_item, :include_assigned_to_group?) do @@ -648,7 +648,7 @@ after_initialize do end add_to_serializer(:search_topic_list_item, :assigned_to_group, false) do - BasicGroupSerializer.new(object.assigned_to, scope: scope, root: false).as_json + AssignedGroupSerializer.new(object.assigned_to, scope: scope, root: false).as_json end add_to_serializer(:search_topic_list_item, "include_assigned_to_group?") do @@ -700,7 +700,7 @@ after_initialize do add_to_serializer(:user_bookmark_base, :assigned_to_group, false) do return if !can_have_assignment? - BasicGroupSerializer.new(assigned_to, scope: scope, root: false).as_json + AssignedGroupSerializer.new(assigned_to, scope: scope, root: false).as_json end add_to_serializer(:user_bookmark_base, "include_assigned_to_group?") do @@ -714,10 +714,6 @@ after_initialize do SiteSetting.assigns_user_url_path.gsub("{username}", object.username) end - add_to_serializer(:basic_group, :assign_icon) { "group-plus" } - - add_to_serializer(:basic_group, :assign_path) { "/g/#{object.name}/assigned/everyone" } - # PostSerializer add_to_serializer(:post, :assigned_to_user) do BasicUserSerializer.new(object.assignment.assigned_to, scope: scope, root: false).as_json @@ -729,7 +725,7 @@ after_initialize do end add_to_serializer(:post, :assigned_to_group, false) do - BasicGroupSerializer.new(object.assignment.assigned_to, scope: scope, root: false).as_json + AssignedGroupSerializer.new(object.assignment.assigned_to, scope: scope, root: false).as_json end add_to_serializer(:post, "include_assigned_to_group?") do diff --git a/spec/requests/search_controller_spec.rb b/spec/requests/search_controller_spec.rb new file mode 100644 index 0000000..4ba60f0 --- /dev/null +++ b/spec/requests/search_controller_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe SearchController do + fab!(:admin) { Fabricate(:admin) } + fab!(:group) do + Fabricate( + :group, + assignable_level: Group::ALIAS_LEVELS[:everyone], + flair_upload: Fabricate(:upload), + ) + end + + before do + SiteSetting.assign_enabled = true + sign_in(admin) + end + + after { Discourse.redis.flushdb } + + it "include assigned group in search result" do + SearchIndexer.enable + SiteSetting.use_pg_headlines_for_excerpt = true + + post = Fabricate(:post, topic: Fabricate(:topic, title: "this is an awesome title")) + + Assigner.new(post.topic, admin).assign(group) + + get "/search/query.json", params: { term: "awesome" } + + expect(response.status).to eq(200) + assigned_to_group_data = response.parsed_body["topics"][0]["assigned_to_group"] + + expect(assigned_to_group_data["id"]).to eq(group.id) + expect(assigned_to_group_data["name"]).to eq(group.name) + expect(assigned_to_group_data["assign_icon"]).to eq("group-plus") + expect(assigned_to_group_data["assign_path"]).to eq("/g/#{group.name}/assigned/everyone") + end +end