Skip to content

Commit 079b3d6

Browse files
committed
Refactor collection reflection
1 parent 1bddd9f commit 079b3d6

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

lib/active_model/serializer/reflection.rb

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -227,16 +227,20 @@ def value(serializer, include_slice)
227227
end
228228

229229
def serialize_association_value!(association_value, serializer_class, parent_serializer, parent_serializer_options)
230-
if (serializer = build_association_serializer(parent_serializer, parent_serializer_options, association_value, serializer_class))
231-
{ serializer: serializer }
230+
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
232242
else
233-
# BUG: per #2027, JSON API resource relationships are only id and type, and hence either
234-
# *require* a serializer or we need to be a little clever about figuring out the id/type.
235-
# In either case, returning the raw virtual value will almost always be incorrect.
236-
#
237-
# Should be reflection_options[:virtual_value] or adapter needs to figure out what to do
238-
# with an object that is non-nil and has no defined serializer.
239-
{ virtual_value: association_value.try(:as_json) || association_value }
243+
{ serializer: build_association_serializer(parent_serializer, parent_serializer_options, association_value, serializer_class) }
240244
end
241245
end
242246

@@ -254,19 +258,24 @@ def build_association_options(parent_serializer, parent_serializer_namespace_opt
254258
end
255259

256260
# NOTE(BF): This serializer throw/catch should only happen when the serializer is a collection
257-
# serializer. This is a good reason for the reflection to have a to_many? or collection? type method.
261+
# serializer.
258262
#
259263
# @return [ActiveModel::Serializer, nil]
260-
def build_association_serializer(parent_serializer, parent_serializer_options, association_value, serializer_class)
264+
def build_association_collection_serializer(parent_serializer, parent_serializer_options, association_value, serializer_class)
261265
catch(:no_serializer) do
262-
# Make all the parent serializer instance options available to associations
263-
# except ActiveModelSerializers-specific ones we don't want.
264-
serializer_options = parent_serializer_options.except(:serializer)
265-
serializer_options[:serializer_context_class] = parent_serializer.class
266-
serializer_options[:serializer] = serializer if serializer
267-
serializer_class.new(association_value, serializer_options)
266+
build_association_serializer(parent_serializer, parent_serializer_options, association_value, serializer_class)
268267
end
269268
end
269+
270+
# @return [ActiveModel::Serializer, nil]
271+
def build_association_serializer(parent_serializer, parent_serializer_options, association_value, serializer_class)
272+
# Make all the parent serializer instance options available to associations
273+
# except ActiveModelSerializers-specific ones we don't want.
274+
serializer_options = parent_serializer_options.except(:serializer)
275+
serializer_options[:serializer_context_class] = parent_serializer.class
276+
serializer_options[:serializer] = serializer if serializer
277+
serializer_class.new(association_value, serializer_options)
278+
end
270279
end
271280
end
272281
end

0 commit comments

Comments
 (0)