Skip to content

Commit 6d0fda2

Browse files
committed
Cache results from Serialization#lookup_serializer
This is especially helpful for serializing "has_many" associations.
1 parent 6afe7c4 commit 6d0fda2

File tree

2 files changed

+23
-19
lines changed

2 files changed

+23
-19
lines changed

lib/transmutation/serialization.rb

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,35 @@ module Serialization
1212
# @return [Transmutation::Serializer] The serialized object. This will respond to `#as_json` and `#to_json`.
1313
def serialize(object, namespace: nil, serializer: nil, depth: 0, max_depth: 1)
1414
if object.respond_to?(:map) && !object.respond_to?(:to_hash)
15-
return object.map do |item|
16-
serialize(item, namespace:, serializer:, depth:, max_depth:)
17-
end
15+
return object.map { |item| serialize(item, namespace:, serializer:, depth:, max_depth:) }
1816
end
1917

20-
lookup_serializer(object, namespace:, serializer:)
21-
.new(object, depth:, max_depth:)
18+
lookup_serializer(object, namespace:, serializer:).new(object, depth:, max_depth:)
2219
end
2320

2421
# Lookup the serializer for the given object.
2522
#
2623
# This calls {Transmutation::Serialization::Lookup#serializer_for} to find the serializer for the given object.
2724
#
25+
# This also caches the result for future lookups.
26+
#
2827
# @param object [Object] The object to lookup the serializer for.
2928
# @param namespace [String, Symbol, Module] The namespace to lookup the serializer in.
3029
# @param serializer [String, Symbol, Class] The serializer to use.
3130
#
3231
# @return [Class<Transmutation::Serializer>] The serializer for the given object.
3332
#
3433
def lookup_serializer(object, namespace: nil, serializer: nil)
35-
Lookup.new(self, namespace:).serializer_for(object, serializer:)
34+
Serialization.cache[[self.namespace, object.class, namespace, serializer]] ||=
35+
Lookup.new(self, namespace:).serializer_for(object, serializer:)
36+
end
37+
38+
def self.cache
39+
@cache ||= {}
40+
end
41+
42+
def namespace
43+
@namespace ||= self.class.name.split("::")[...-1].join("::")
3644
end
3745

3846
private_class_method def self.included(base)

lib/transmutation/serialization/lookup.rb

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ def initialize(caller, namespace: nil)
1818
# namespace: Api::V1::Admin::Detailed
1919
# serializer: Chat::User
2020
#
21-
# This method will attempt to find a serializer defined in the following order:
21+
# # This method will attempt to find a serializer defined in the following order:
2222
#
23-
# - Api::V1::Admin::Detailed::Chat::UserSerializer
24-
# - Api::V1::Admin::Chat::UserSerializer
25-
# - Api::V1::Chat::UserSerializer
26-
# - Api::Chat::UserSerializer
27-
# - Chat::UserSerializer
23+
# # - Api::V1::Admin::Detailed::Chat::UserSerializer
24+
# # - Api::V1::Admin::Chat::UserSerializer
25+
# # - Api::V1::Chat::UserSerializer
26+
# # - Api::Chat::UserSerializer
27+
# # - Chat::UserSerializer
2828
def serializer_for(object, serializer: nil)
2929
serializer_name = serializer_name_for(object, serializer:)
3030

@@ -65,14 +65,10 @@ def potential_namespaces
6565
end
6666

6767
def serializer_namespace
68-
return caller_namespace if @namespace.nil?
69-
return @namespace if @namespace.start_with?("::")
68+
return @caller.namespace if @namespace.nil?
69+
return @namespace if @namespace.start_with?("::")
7070

71-
"#{caller_namespace}::#{@namespace}"
72-
end
73-
74-
def caller_namespace
75-
@caller_namespace ||= @caller.class.name.split("::")[...-1].join("::")
71+
"#{@caller.namespace}::#{@namespace}"
7672
end
7773

7874
def constantize_serializer!(namespace, name, object:)

0 commit comments

Comments
 (0)