class ActiveModel::Serializer

Constants

Association

This class holds all information about serializer's association.

@api private

Field

Holds all the meta-data about a field (i.e. attribute or association) as it was specified in the ActiveModel::Serializer class. Notice that the field block is evaluated in the context of the serializer.

LazyAssociation

@api private

SERIALIZABLE_HASH_VALID_KEYS

@see serializable_hash for more details on these valid keys.

UndefinedCacheKey
VERSION

Attributes

instance_options[RW]
instance_reflections[RW]
object[RW]

END SERIALIZER MACROS

root[RW]

END SERIALIZER MACROS

scope[RW]

END SERIALIZER MACROS

Public Class Methods

_attributes() click to toggle source

@return [Array<Symbol>] Key names of declared attributes @see Serializer::attribute

# File lib/active_model/serializer.rb, line 196
def self._attributes
  _attributes_data.keys
end
adapter() click to toggle source

@see ActiveModelSerializers::Adapter.lookup Deprecated

# File lib/active_model/serializer.rb, line 57
def self.adapter
  ActiveModelSerializers::Adapter.lookup(config.adapter)
end
attribute(attr, options = {}, &block) click to toggle source

@example

class AdminAuthorSerializer < ActiveModel::Serializer
  attributes :id, :recent_edits
  attribute :name, key: :title

  attribute :full_name do
    "#{object.first_name} #{object.last_name}"
  end

  def recent_edits
    object.edits.last(5)
  end
# File lib/active_model/serializer.rb, line 225
def self.attribute(attr, options = {}, &block)
  key = options.fetch(:key, attr)
  _attributes_data[key] = Attribute.new(attr, options, block)
end
attributes(*attrs) click to toggle source

@example

class AdminAuthorSerializer < ActiveModel::Serializer
  attributes :id, :name, :recent_edits
# File lib/active_model/serializer.rb, line 205
def self.attributes(*attrs)
  attrs = attrs.first if attrs.first.class == Array

  attrs.each do |attr|
    attribute(attr)
  end
end
belongs_to(name, options = {}, &block) click to toggle source

@param [Symbol] name of the association @param [Hash<Symbol => any>] options for the reflection @return [void]

@example

belongs_to :author, serializer: AuthorSerializer
# File lib/active_model/serializer.rb, line 248
def self.belongs_to(name, options = {}, &block)
  associate(BelongsToReflection.new(name, options, block))
end
get_serializer_for(klass, namespace = nil) click to toggle source

@api private Find a serializer from a class and caches the lookup. Preferentially returns:

1. class name appended with "Serializer"
2. try again with superclass, if present
3. nil
# File lib/active_model/serializer.rb, line 85
def self.get_serializer_for(klass, namespace = nil)
  return nil unless config.serializer_lookup_enabled

  cache_key = ActiveSupport::Cache.expand_cache_key(klass, namespace)
  serializers_cache.fetch_or_store(cache_key) do
    # NOTE(beauby): When we drop 1.9.3 support we can lazify the map for perfs.
    lookup_chain = serializer_lookup_chain_for(klass, namespace)
    serializer_class = lookup_chain.map(&:safe_constantize).find { |x| x && x < ActiveModel::Serializer }

    if serializer_class
      serializer_class
    elsif klass.superclass
      get_serializer_for(klass.superclass)
    else
      nil # No serializer found
    end
  end
end
has_many(name, options = {}, &block) click to toggle source

@param [Symbol] name of the association @param [Hash<Symbol => any>] options for the reflection @return [void]

@example

has_many :comments, serializer: CommentSummarySerializer
# File lib/active_model/serializer.rb, line 237
def self.has_many(name, options = {}, &block) # rubocop:disable Style/PredicateName
  associate(HasManyReflection.new(name, options, block))
end
has_one(name, options = {}, &block) click to toggle source

@param [Symbol] name of the association @param [Hash<Symbol => any>] options for the reflection @return [void]

@example

has_one :author, serializer: AuthorSerializer
# File lib/active_model/serializer.rb, line 259
def self.has_one(name, options = {}, &block) # rubocop:disable Style/PredicateName
  associate(HasOneReflection.new(name, options, block))
end
include_directive_from_options(options) click to toggle source

@api private

# File lib/active_model/serializer.rb, line 105
def self.include_directive_from_options(options)
  if options[:include_directive]
    options[:include_directive]
  elsif options[:include]
    JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true)
  else
    ActiveModelSerializers.default_include_directive
  end
end
inherited(base) click to toggle source
Calls superclass method
# File lib/active_model/serializer.rb, line 187
def self.inherited(base)
  super
  base._attributes_data = _attributes_data.dup
  base._reflections = _reflections.dup
  base._links = _links.dup
end
meta(value = nil, &block) click to toggle source

Set the JSON API meta attribute of a serializer. @example

class AdminAuthorSerializer < ActiveModel::Serializer
  meta { stuff: 'value' }

@example

meta do
  { comment_count: object.comments.count }
end
# File lib/active_model/serializer.rb, line 299
def self.meta(value = nil, &block)
  self._meta = block || value
end
new(object, options = {}) click to toggle source

`scope_name` is set as :current_user by default in the controller. If the instance does not have a method named `scope_name`, it defines the method so that it calls the scope.

# File lib/active_model/serializer.rb, line 318
def initialize(object, options = {})
  self.object = object
  self.instance_options = options
  self.root = instance_options[:root]
  self.scope = instance_options[:scope]

  return if !(scope_name = instance_options[:scope_name]) || respond_to?(scope_name)

  define_singleton_method scope_name, -> { scope }
end
serialization_adapter_instance() click to toggle source

@api private

# File lib/active_model/serializer.rb, line 116
def self.serialization_adapter_instance
  @serialization_adapter_instance ||= ActiveModelSerializers::Adapter::Attributes
end
serializer_for(resource_or_class, options = {}) click to toggle source

@param resource [ActiveRecord::Base, ActiveModelSerializers::Model] @return [ActiveModel::Serializer]

Preferentially returns
1. resource.serializer_class
2. ArraySerializer when resource is a collection
3. options[:serializer]
4. lookup serializer when resource is a Class
# File lib/active_model/serializer.rb, line 44
def self.serializer_for(resource_or_class, options = {})
  if resource_or_class.respond_to?(:serializer_class)
    resource_or_class.serializer_class
  elsif resource_or_class.respond_to?(:to_ary)
    config.collection_serializer
  else
    resource_class = resource_or_class.class == Class ? resource_or_class : resource_or_class.class
    options.fetch(:serializer) { get_serializer_for(resource_class, options[:namespace]) }
  end
end
serializer_lookup_chain_for(klass, namespace = nil) click to toggle source

@api private

# File lib/active_model/serializer.rb, line 66
def self.serializer_lookup_chain_for(klass, namespace = nil)
  lookups = ActiveModelSerializers.config.serializer_lookup_chain
  Array[*lookups].flat_map do |lookup|
    lookup.call(klass, self, namespace)
  end.compact
end
serializers_cache() click to toggle source

Used to cache serializer name => serializer class when looked up by Serializer.get_serializer_for.

# File lib/active_model/serializer.rb, line 75
def self.serializers_cache
  @serializers_cache ||= ThreadSafe::Cache.new
end
type(type) click to toggle source

Set the JSON API type of a serializer. @example

class AdminAuthorSerializer < ActiveModel::Serializer
  type 'authors'
# File lib/active_model/serializer.rb, line 307
def self.type(type)
  self._type = type && type.to_s
end

Private Class Methods

associate(reflection) click to toggle source

Add reflection and define {name} accessor. @param [ActiveModel::Serializer::Reflection] reflection @return [void]

@api private

# File lib/active_model/serializer.rb, line 268
def self.associate(reflection)
  key = reflection.options[:key] || reflection.name
  self._reflections[key] = reflection
end

Public Instance Methods

as_json(adapter_opts = nil) click to toggle source

@see serializable_hash

# File lib/active_model/serializer.rb, line 376
def as_json(adapter_opts = nil)
  serializable_hash(adapter_opts)
end
associations(include_directive = ActiveModelSerializers.default_include_directive, include_slice = nil) click to toggle source

@param [JSONAPI::IncludeDirective] include_directive (defaults to the

+default_include_directive+ config value when not provided)

@return [Enumerator<Association>]

# File lib/active_model/serializer.rb, line 347
def associations(include_directive = ActiveModelSerializers.default_include_directive, include_slice = nil)
  include_slice ||= include_directive
  return Enumerator.new {} unless object

  Enumerator.new do |y|
    (self.instance_reflections ||= self.class._reflections.deep_dup).each do |key, reflection|
      next if reflection.excluded?(self)
      next unless include_directive.key?(key)

      association = reflection.build_association(self, instance_options, include_slice)
      y.yield association
    end
  end
end
associations_hash(adapter_options, options, adapter_instance) click to toggle source

@api private

# File lib/active_model/serializer.rb, line 405
def associations_hash(adapter_options, options, adapter_instance)
  include_directive = options.fetch(:include_directive)
  include_slice = options[:include_slice]
  associations(include_directive, include_slice).each_with_object({}) do |association, relationships|
    adapter_opts = adapter_options.merge(include_directive: include_directive[association.key], adapter_instance: adapter_instance)
    relationships[association.key] = association.serializable_hash(adapter_opts, adapter_instance)
  end
end
attributes(requested_attrs = nil, reload = false) click to toggle source

Return the attributes of object as presented by the serializer.

# File lib/active_model/serializer.rb, line 335
def attributes(requested_attrs = nil, reload = false)
  @attributes = nil if reload
  @attributes ||= self.class._attributes_data.each_with_object({}) do |(key, attr), hash|
    next if attr.excluded?(self)
    next unless requested_attrs.nil? || requested_attrs.include?(key)
    hash[key] = attr.value(self)
  end
end
attributes_hash(_adapter_options, options, adapter_instance) click to toggle source

@api private

# File lib/active_model/serializer.rb, line 394
def attributes_hash(_adapter_options, options, adapter_instance)
  if self.class.cache_enabled?
    fetch_attributes(options[:fields], options[:cached_attributes] || {}, adapter_instance)
  elsif self.class.fragment_cache_enabled?
    fetch_attributes_fragment(adapter_instance, options[:cached_attributes] || {})
  else
    attributes(options[:fields], true)
  end
end
json_key() click to toggle source

Used by adapter as resource root.

# File lib/active_model/serializer.rb, line 381
def json_key
  root || _type || object.class.model_name.to_s.underscore
end
read_attribute_for_serialization(attr) click to toggle source
# File lib/active_model/serializer.rb, line 385
def read_attribute_for_serialization(attr)
  if respond_to?(attr)
    send(attr)
  else
    object.read_attribute_for_serialization(attr)
  end
end
serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance) click to toggle source

@return [Hash] containing the attributes and first level associations, similar to how ActiveModel::Serializers::JSON is used in ActiveRecord::Base.

# File lib/active_model/serializer.rb, line 365
def serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance)
  adapter_options ||= {}
  options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options)
  resource = attributes_hash(adapter_options, options, adapter_instance)
  relationships = associations_hash(adapter_options, options, adapter_instance)
  resource.merge(relationships)
end
Also aliased as: to_hash, to_h
success?() click to toggle source
# File lib/active_model/serializer.rb, line 329
def success?
  true
end
to_h(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance)
Alias for: serializable_hash
to_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance)
Alias for: serializable_hash