From d23f7af3cbe8d9bc7c07db01ff7fb72275943174 Mon Sep 17 00:00:00 2001
From: David Taylor <david@taylorhq.com>
Date: Tue, 3 Mar 2020 13:56:54 +0000
Subject: [PATCH] PERF: Allow user serializer to make use of preloaded custom
 fields (#9074)

---
 app/models/concerns/has_custom_fields.rb |  4 ++++
 app/serializers/user_card_serializer.rb  | 19 +++++++++++++------
 app/serializers/user_serializer.rb       | 12 ++++++++++++
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/app/models/concerns/has_custom_fields.rb b/app/models/concerns/has_custom_fields.rb
index 923efe846db..64cafe6f7a5 100644
--- a/app/models/concerns/has_custom_fields.rb
+++ b/app/models/concerns/has_custom_fields.rb
@@ -142,6 +142,10 @@ module HasCustomFields
     super
   end
 
+  def custom_fields_preloaded?
+    !!@preloaded_custom_fields
+  end
+
   def custom_field_preloaded?(name)
     @preloaded_custom_fields && @preloaded_custom_fields.key?(name)
   end
diff --git a/app/serializers/user_card_serializer.rb b/app/serializers/user_card_serializer.rb
index 5d53a6258c6..6b7f59cd40d 100644
--- a/app/serializers/user_card_serializer.rb
+++ b/app/serializers/user_card_serializer.rb
@@ -149,14 +149,14 @@ class UserCardSerializer < BasicUserSerializer
   end
 
   def custom_fields
-    fields = User.whitelisted_user_custom_fields(scope)
-
-    if scope.can_edit?(object)
-      fields += DiscoursePluginRegistry.serialized_current_user_fields.to_a
-    end
+    fields = custom_field_keys
 
     if fields.present?
-      User.custom_fields_for_ids([object.id], fields)[object.id] || {}
+      if object.custom_fields_preloaded?
+        {}.tap { |h| fields.each { |f| h[f] = object.custom_fields[f] } }
+      else
+        User.custom_fields_for_ids([object.id], fields)[object.id] || {}
+      end
     else
       {}
     end
@@ -197,4 +197,11 @@ class UserCardSerializer < BasicUserSerializer
   def card_background_upload_url
     object.card_background_upload&.url
   end
+
+  private
+
+  def custom_field_keys
+    # Can be extended by other serializers
+    User.whitelisted_user_custom_fields(scope)
+  end
 end
diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb
index d92f0e4224b..866dc39a8d6 100644
--- a/app/serializers/user_serializer.rb
+++ b/app/serializers/user_serializer.rb
@@ -270,4 +270,16 @@ class UserSerializer < UserCardSerializer
     object.profile_background_upload&.url
   end
 
+  private
+
+  def custom_field_keys
+    fields = super
+
+    if scope.can_edit?(object)
+      fields += DiscoursePluginRegistry.serialized_current_user_fields.to_a
+    end
+
+    fields
+  end
+
 end