@@ -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