Closed
Description
from: #1156 (comment)
So, AMS doesn't handle primitives, and when they find their way it, they are passed through as is. ( Specifically, when you're not rendering an object with a defined serializer.)
How options are parsed
- ActionControllerSerialization
serializable_resource = ActiveModel::SerializableResource.new(resource, options)
- ActiveModel::SerializableResource
if serializable_resource.serializer?
- Where
serializer?
isuse_adapter? && !!(serializer)
- Where
use_adapter?
: 'True when no explicit adapter given, or explicit value is truthy (non-nil); False when explicit adapter is falsy (nil or false)' - Where
serializer
:- from explicit
:serializer
option, else - implicitly from resource
ActiveModel::Serializer.serializer_for(resource)
- from explicit
- Where
- Where
- A side-effect of checking
serializer
is:- The
:serializer
option is removed from the serializer_opts hash - If the
:each_serializer
option is present, it is removed from the serializer_opts hash and set as the:serializer
option
- The
- The serializer and adapter are created as
serializer_instance = serializer.new(resource, serializer_opts)
adapter_instance = ActiveModel::Serializer::Adapter.create(serializer_instance, adapter_opts)
- AcitveModel::Serializer::ArraySerializer#new
- If the
serializer_instance
was aArraySerializer
and the:serializer
serializer_opts is present, then that serializer is passed into each resource: - ActiveModel::Serializer#attributes is used by the adapter to get the attributes for resource as defined by the serializer.
The upshot of which is that
- for a collection, the collection serializer is the
:serializer
option and:each_serializer
is used as the serializer for each resource in the collection - for a single resource, the
:serializer
option is the resource serializer
Aside, if the collection serializer (ArraySerializer) cannot identify a serializer for a resource in its collection, it raises NoSerializerError
which is rescued in AcitveModel::Serializer::Reflection#build_association
which sets the association value directly: reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
(which is called by the adapter as serializer.associations(*)