Skip to content

Commit ee69293

Browse files
committed
Refactor reflection building serializer class
1 parent 079b3d6 commit ee69293

File tree

1 file changed

+19
-25
lines changed

1 file changed

+19
-25
lines changed

lib/active_model/serializer/reflection.rb

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,24 @@ def to_many?
147147
# @api private
148148
def build_association(parent_serializer, parent_serializer_options, include_slice = {})
149149
reflection_options = settings.merge(include_data: include_data?(include_slice)) unless block?
150-
association_options = build_association_options(parent_serializer, parent_serializer_options[:namespace], include_slice)
151-
association_value = association_options[:association_value]
152-
serializer_class = association_options[:association_serializer]
150+
151+
association_value = value(parent_serializer, include_slice)
152+
serializer_class = build_serializer_class(association_value, parent_serializer, parent_serializer_options[:namespace])
153153

154154
reflection_options ||= settings.merge(include_data: include_data?(include_slice)) # Needs to be after association_value is evaluated unless reflection.block.nil?
155155

156156
if serializer_class
157-
reflection_options.merge!(
158-
serialize_association_value!(association_value, serializer_class, parent_serializer, parent_serializer_options)
159-
)
157+
if (serializer = build_serializer!(association_value, serializer_class, parent_serializer, parent_serializer_options))
158+
reflection_options[:serializer] = serializer
159+
else
160+
# BUG: per #2027, JSON API resource relationships are only id and type, and hence either
161+
# *require* a serializer or we need to be a little clever about figuring out the id/type.
162+
# In either case, returning the raw virtual value will almost always be incorrect.
163+
#
164+
# Should be reflection_options[:virtual_value] or adapter needs to figure out what to do
165+
# with an object that is non-nil and has no defined serializer.
166+
reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
167+
end
160168
elsif !association_value.nil? && !association_value.instance_of?(Object)
161169
reflection_options[:virtual_value] = association_value
162170
end
@@ -226,35 +234,21 @@ def value(serializer, include_slice)
226234
end
227235
end
228236

229-
def serialize_association_value!(association_value, serializer_class, parent_serializer, parent_serializer_options)
237+
def build_serializer!(association_value, serializer_class, parent_serializer, parent_serializer_options)
230238
if to_many?
231-
if (serializer = build_association_collection_serializer(parent_serializer, parent_serializer_options, association_value, serializer_class))
232-
{ serializer: serializer }
233-
else
234-
# BUG: per #2027, JSON API resource relationships are only id and type, and hence either
235-
# *require* a serializer or we need to be a little clever about figuring out the id/type.
236-
# In either case, returning the raw virtual value will almost always be incorrect.
237-
#
238-
# Should be reflection_options[:virtual_value] or adapter needs to figure out what to do
239-
# with an object that is non-nil and has no defined serializer.
240-
{ virtual_value: association_value.try(:as_json) || association_value }
241-
end
239+
build_association_collection_serializer(parent_serializer, parent_serializer_options, association_value, serializer_class)
242240
else
243-
{ serializer: build_association_serializer(parent_serializer, parent_serializer_options, association_value, serializer_class) }
241+
build_association_serializer(parent_serializer, parent_serializer_options, association_value, serializer_class)
244242
end
245243
end
246244

247-
def build_association_options(parent_serializer, parent_serializer_namespace_option, include_slice)
245+
def build_serializer_class(association_value, parent_serializer, parent_serializer_namespace_option)
248246
serializer_for_options = {
249247
# Pass the parent's namespace onto the child serializer
250248
namespace: namespace || parent_serializer_namespace_option
251249
}
252250
serializer_for_options[:serializer] = serializer if serializer?
253-
association_value = value(parent_serializer, include_slice)
254-
{
255-
association_value: association_value,
256-
association_serializer: parent_serializer.class.serializer_for(association_value, serializer_for_options)
257-
}
251+
parent_serializer.class.serializer_for(association_value, serializer_for_options)
258252
end
259253

260254
# NOTE(BF): This serializer throw/catch should only happen when the serializer is a collection

0 commit comments

Comments
 (0)