Skip to content

Document serializer/each_serializer options #1191

Closed
@bf4

Description

@bf4

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

  1. ActionControllerSerialization
  2. serializable_resource = ActiveModel::SerializableResource.new(resource, options)
  3. ActiveModel::SerializableResource
  4. if serializable_resource.serializer?
    • Where serializer? is use_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:
        1. from explicit :serializer option, else
        2. implicitly from resource ActiveModel::Serializer.serializer_for(resource)
  5. 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
  6. The serializer and adapter are created as
    1. serializer_instance = serializer.new(resource, serializer_opts)
    2. adapter_instance = ActiveModel::Serializer::Adapter.create(serializer_instance, adapter_opts)
  7. AcitveModel::Serializer::ArraySerializer#new
  8. If the serializer_instance was a ArraySerializer and the :serializer serializer_opts is present, then that serializer is passed into each resource:
    serializer_class = options.fetch(:serializer) do
    ActiveModel::Serializer.serializer_for(resource)
    end
  9. 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(*)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions