FIX: Make category-drop work with lazy_load_categories (#24187)

The category drop was rerendered after every category async change
because it updated the categories list. This is not necessary and
categories can be referenced indirectly by ID instead.
This commit is contained in:
Bianca Nenciu
2023-11-28 17:58:47 +02:00
committed by GitHub
parent 21d614215b
commit e85a81f33c
17 changed files with 165 additions and 63 deletions

View File

@@ -107,12 +107,13 @@ class Category < ActiveRecord::Base
before_save :downcase_name
before_save :ensure_category_setting
after_save :publish_discourse_stylesheet
after_save :publish_category
after_save :reset_topic_ids_cache
after_save :clear_subcategory_ids
after_save :clear_parent_ids
after_save :clear_url_cache
after_save :update_reviewables
after_save :publish_discourse_stylesheet
after_save :publish_category
after_save do
if saved_change_to_uploaded_logo_id? || saved_change_to_uploaded_logo_dark_id? ||
@@ -128,6 +129,8 @@ class Category < ActiveRecord::Base
end
after_destroy :reset_topic_ids_cache
after_destroy :clear_subcategory_ids
after_destroy :clear_parent_ids
after_destroy :publish_category_deletion
after_destroy :remove_site_settings
@@ -197,6 +200,19 @@ class Category < ActiveRecord::Base
scope :post_create_allowed,
->(guardian) { scoped_to_permissions(guardian, POST_CREATION_PERMISSIONS) }
scope :with_ancestors, ->(id) { where(<<~SQL, id) }
id IN (
WITH RECURSIVE ancestors(category_id) AS (
SELECT ?
UNION
SELECT parent_category_id
FROM categories, ancestors
WHERE id = ancestors.category_id
)
SELECT category_id FROM ancestors
)
SQL
delegate :post_template, to: "self.class"
# permission is just used by serialization
@@ -843,9 +859,24 @@ class Category < ActiveRecord::Base
self.where("string_to_array(email_in, '|') @> ARRAY[?]", Email.downcase(email)).first
end
@@has_children = DistributedCache.new("has_children")
def self.has_children?(category_id)
@@has_children.defer_get_set(category_id.to_s) do
Category.where(parent_category_id: category_id).exists?
end
end
def has_children?
@has_children ||= (id && Category.where(parent_category_id: id).exists?) ? :true : :false
@has_children == :true
!!id && Category.has_children?(id)
end
def self.clear_parent_ids
@@has_children.clear
end
def clear_parent_ids
Category.clear_parent_ids
end
def uncategorized?

View File

@@ -5,7 +5,7 @@ class Site
include ActiveModel::Serialization
# Number of categories preloaded when lazy_load_categories is enabled
LAZY_LOAD_CATEGORIES_LIMIT = 50
LAZY_LOAD_CATEGORIES_LIMIT = 10
cattr_accessor :preloaded_category_custom_fields
@@ -120,10 +120,6 @@ class Site
)
categories << category
end
if SiteSetting.lazy_load_categories && categories.size >= Site::LAZY_LOAD_CATEGORIES_LIMIT
break
end
end
with_children = Set.new
@@ -161,7 +157,11 @@ class Site
self.class.categories_callbacks.each { |callback| callback.call(categories, @guardian) }
categories
if SiteSetting.lazy_load_categories
categories[0...Site::LAZY_LOAD_CATEGORIES_LIMIT]
else
categories
end
end
end