FIX: Load categories with search topic results (#25700)

Add categories to the serialized search results together with the topics
when lazy load categories is enabled. This is necessary in order for the
results to be rendered correctly and display the category information.
This commit is contained in:
Bianca Nenciu 2024-02-21 17:29:47 +02:00 committed by GitHub
parent d8c3924213
commit 9199c52e5e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 88 additions and 3 deletions

View File

@ -9,6 +9,7 @@ import userSearch from "discourse/lib/user-search";
import { escapeExpression } from "discourse/lib/utilities";
import Category from "discourse/models/category";
import Post from "discourse/models/post";
import Site from "discourse/models/site";
import Topic from "discourse/models/topic";
import User from "discourse/models/user";
import getURL from "discourse-common/lib/get-url";
@ -56,10 +57,15 @@ export function translateResults(results, opts) {
results.categories = results.categories
.map(function (category) {
Site.current().updateCategory(category);
return Category.list().findBy("id", category.id || category.model.id);
})
.compact();
results.grouped_search_result?.extra?.categories?.forEach((category) =>
Site.current().updateCategory(category)
);
results.groups = results.groups
.map((group) => {
const name = escapeExpression(group.name);

View File

@ -13,7 +13,8 @@ class GroupedSearchResultSerializer < ApplicationSerializer
:search_log_id,
:more_full_page_results,
:can_create_topic,
:error
:error,
:extra
def search_log_id
object.search_log_id
@ -30,4 +31,17 @@ class GroupedSearchResultSerializer < ApplicationSerializer
def can_create_topic
scope.can_create?(Topic)
end
def extra
extra = {}
if object.can_lazy_load_categories
extra[:categories] = ActiveModel::ArraySerializer.new(
object.extra_categories,
each_serializer: BasicCategorySerializer,
)
end
extra
end
end

View File

@ -266,6 +266,7 @@ class Search
search_context: @search_context,
blurb_length: @blurb_length,
is_header_search: !use_full_page_limit,
can_lazy_load_categories: @guardian.can_lazy_load_categories?,
)
end
@ -1447,7 +1448,7 @@ class Search
def posts_eager_loads(query)
query = query.includes(:user, :post_search_data)
topic_eager_loads = [:category]
topic_eager_loads = [{ category: :parent_category }]
topic_eager_loads << :tags if SiteSetting.tagging_enabled

View File

@ -14,6 +14,7 @@ class Search
:type_filter,
:posts,
:categories,
:extra_categories,
:users,
:tags,
:groups,
@ -25,6 +26,7 @@ class Search
:more_full_page_results,
:error,
:use_pg_headlines_for_excerpt,
:can_lazy_load_categories,
)
attr_accessor :search_log_id
@ -38,7 +40,8 @@ class Search
blurb_length: nil,
blurb_term: nil,
is_header_search: false,
use_pg_headlines_for_excerpt: SiteSetting.use_pg_headlines_for_excerpt
use_pg_headlines_for_excerpt: SiteSetting.use_pg_headlines_for_excerpt,
can_lazy_load_categories: false
)
@type_filter = type_filter
@term = term
@ -47,12 +50,14 @@ class Search
@blurb_length = blurb_length || BLURB_LENGTH
@posts = []
@categories = []
@extra_categories = Set.new
@users = []
@tags = []
@groups = []
@error = nil
@is_header_search = is_header_search
@use_pg_headlines_for_excerpt = use_pg_headlines_for_excerpt
@can_lazy_load_categories = can_lazy_load_categories
end
def error=(error)
@ -101,6 +106,21 @@ class Search
else
(self.public_send(type)) << object
end
if can_lazy_load_categories
category =
case type
when "posts"
object.topic.category
when "topics"
object.category
end
if category
extra_categories << category.parent_category if category.parent_category
extra_categories << category
end
end
end
def self.blurb_for(cooked: nil, term: nil, blurb_length: BLURB_LENGTH, scrub: true)

View File

@ -74,6 +74,17 @@
"null"
]
},
"extra": {
"type": "object",
"properties": {
"categories": {
"type": [
"array",
"null"
]
}
}
},
"post_ids": {
"type": "array",
"items": {

View File

@ -495,6 +495,39 @@ RSpec.describe SearchController do
end
end
end
context "with lazy loaded categories" do
fab!(:parent_category) { Fabricate(:category) }
fab!(:category) { Fabricate(:category, parent_category: parent_category) }
fab!(:other_category) { Fabricate(:category, parent_category: parent_category) }
fab!(:post) do
with_search_indexer_enabled do
topic = Fabricate(:topic, category: category)
Fabricate(:post, topic: topic, raw: "hello world. first topic")
end
end
fab!(:other_post) do
with_search_indexer_enabled do
topic = Fabricate(:topic, category: other_category)
Fabricate(:post, topic: topic, raw: "hello world. second topic")
end
end
before { SiteSetting.lazy_load_categories_groups = "#{Group::AUTO_GROUPS[:everyone]}" }
it "returns extra categories and parent categories" do
get "/search.json", params: { q: "hello" }
categories = response.parsed_body["grouped_search_result"]["extra"]["categories"]
expect(categories.map { |c| c["id"] }).to contain_exactly(
parent_category.id,
category.id,
other_category.id,
)
end
end
end
context "with search priority" do