DEV: Option to preload category custom fields for site serializer

DEV: Option to preload category custom fields for site serializer

diff --git a/app/models/site.rb b/app/models/site.rb
index 4dbff4b..a37944e 100644
--- a/app/models/site.rb
+++ b/app/models/site.rb
@@ -5,8 +5,12 @@ require_dependency 'trust_level'
 class Site
   include ActiveModel::Serialization
 
+  cattr_accessor :preloaded_category_custom_fields
+  self.preloaded_category_custom_fields = Set.new
+
   def initialize(guardian)
     @guardian = guardian
+    Category.preload_custom_fields(categories, preloaded_category_custom_fields) if preloaded_category_custom_fields.present?
   end
 
   def site_setting
diff --git a/app/serializers/basic_category_serializer.rb b/app/serializers/basic_category_serializer.rb
index 806f0cc..417eab2 100644
--- a/app/serializers/basic_category_serializer.rb
+++ b/app/serializers/basic_category_serializer.rb
@@ -26,7 +26,8 @@ class BasicCategorySerializer < ApplicationSerializer
              :subcategory_list_style,
              :default_top_period,
              :minimum_required_tags,
-             :navigate_to_first_post_after_read
+             :navigate_to_first_post_after_read,
+             :custom_fields
 
   has_one :uploaded_logo, embed: :object, serializer: CategoryUploadSerializer
   has_one :uploaded_background, embed: :object, serializer: CategoryUploadSerializer
@@ -54,4 +55,12 @@ class BasicCategorySerializer < ApplicationSerializer
   def notification_level
     object.notification_level
   end
+
+  def custom_fields
+    object.preloaded_custom_fields
+  end
+
+  def include_custom_fields?
+    custom_fields.present?
+  end
 end
diff --git a/app/serializers/category_serializer.rb b/app/serializers/category_serializer.rb
index ee7b593..30540b1 100644
--- a/app/serializers/category_serializer.rb
+++ b/app/serializers/category_serializer.rb
@@ -97,4 +97,8 @@ class CategorySerializer < BasicCategorySerializer
   def allowed_tag_groups
     object.tag_groups.pluck(:name)
   end
+
+  def custom_fields
+    object.custom_fields
+  end
 end
diff --git a/spec/serializers/category_serializer_spec.rb b/spec/serializers/category_serializer_spec.rb
new file mode 100644
index 0000000..8f5a286
--- /dev/null
+++ b/spec/serializers/category_serializer_spec.rb
@@ -0,0 +1,14 @@
+require 'rails_helper'
+require_dependency 'category'
+
+describe CategorySerializer do
+  let(:category) { Fabricate(:category) }
+
+  it "includes custom fields" do
+    category.custom_fields["enable_marketplace"] = true
+    category.save_custom_fields
+
+    json = described_class.new(category, scope: Guardian.new, root: false).as_json
+    expect(json[:custom_fields]).to be_present
+  end
+end
diff --git a/spec/serializers/site_serializer_spec.rb b/spec/serializers/site_serializer_spec.rb
new file mode 100644
index 0000000..ade1cab
--- /dev/null
+++ b/spec/serializers/site_serializer_spec.rb
@@ -0,0 +1,20 @@
+require 'rails_helper'
+require_dependency 'site'
+
+describe SiteSerializer do
+  let(:guardian) { Guardian.new }
+
+  it "includes category custom fields only if its preloaded" do
+    category = Fabricate(:category)
+    category.custom_fields["enable_marketplace"] = true
+    category.save_custom_fields
+
+    data = MultiJson.dump(described_class.new(Site.new(guardian), scope: guardian, root: false))
+    expect(data).not_to include("enable_marketplace")
+
+    Site.preloaded_category_custom_fields << "enable_marketplace"
+
+    data = MultiJson.dump(described_class.new(Site.new(guardian), scope: guardian, root: false))
+    expect(data).to include("enable_marketplace")
+  end
+end

GitHub sha: 4477938e

Will this be OK since it is overriding object.preloaded_custom_fields from the parent class?

Yes, category serializer loads all custom fields by default. It’s working in the same way even before my commit.

Sorry I meant why do we need to include the custom_fields attribute in the serializer when no code in core is currently using it?

CategorySerializer already includes custom_fields attribute here from this commit. In this commit I’m just making sure it returns all the custom fields instead of preloaded.

1 Like

ahhh ok. Thanks for explaining :+1:

2 Likes