Class: ActiveModel::Serializer

Inherits:
Object
  • Object
show all
Extended by:
ActiveModelSerializers::Deprecate, ActiveSupport::Autoload
Includes:
Associations, Attributes, Caching, Configuration, Links, Meta, Type
Defined in:
lib/active_model/serializer.rb,
lib/active_model/serializer/meta.rb,
lib/active_model/serializer/type.rb,
lib/active_model/serializer/null.rb,
lib/active_model/serializer/field.rb,
lib/active_model/serializer/links.rb,
lib/active_model/serializer/adapter.rb,
lib/active_model/serializer/version.rb,
lib/active_model/serializer/caching.rb,
lib/active_model/serializer/fieldset.rb,
lib/active_model/serializer/attribute.rb,
lib/active_model/serializer/reflection.rb,
lib/active_model/serializer/attributes.rb,
lib/active_model/serializer/association.rb,
lib/active_model/serializer/adapter/json.rb,
lib/active_model/serializer/adapter/null.rb,
lib/active_model/serializer/adapter/base.rb,
lib/active_model/serializer/associations.rb,
lib/active_model/serializer/configuration.rb,
lib/active_model/serializer/adapter/json_api.rb,
lib/active_model/serializer/array_serializer.rb,
lib/active_model/serializer/adapter/attributes.rb,
lib/active_model/serializer/has_one_reflection.rb,
lib/active_model/serializer/singular_reflection.rb,
lib/active_model/serializer/has_many_reflection.rb,
lib/active_model/serializer/collection_reflection.rb,
lib/active_model/serializer/belongs_to_reflection.rb,
lib/active_model/serializer/collection_serializer.rb

Direct Known Subclasses

ErrorSerializer, Null

Defined Under Namespace

Modules: Adapter, Associations, Attributes, Caching, Configuration, Links, Lint, Meta, Type Classes: ArraySerializer, Association, Attribute, BelongsToReflection, CollectionReflection, CollectionSerializer, ErrorSerializer, ErrorsSerializer, Field, Fieldset, HasManyReflection, HasOneReflection, Null, Reflection, SingularReflection

Constant Summary

SERIALIZABLE_HASH_VALID_KEYS =
[:only, :except, :methods, :include, :root].freeze
VERSION =
'0.10.0'.freeze
UndefinedCacheKey =
Class.new(StandardError)

Constants included from Caching

Caching::CALLER_FILE

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from ActiveModelSerializers::Deprecate

delegate_and_deprecate, deprecate

Methods included from Caching

#cache_key, #fetch, #fetch_attributes, #fetch_attributes_fragment, #object_cache_key, #serializer_class

Methods included from Associations

#associations

Constructor Details

- (Serializer) initialize(object, options = {})

`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.



122
123
124
125
126
127
128
129
130
131
132
# File 'lib/active_model/serializer.rb', line 122

def initialize(object, options = {})
  self.object = object
  self.instance_options = options
  self.root = instance_options[:root]
  self.scope = instance_options[:scope]

  scope_name = instance_options[:scope_name]
  if scope_name && !respond_to?(scope_name)
    define_singleton_method scope_name, lambda { scope }
  end
end

Instance Attribute Details

- (Object) object

Returns the value of attribute object



117
118
119
# File 'lib/active_model/serializer.rb', line 117

def object
  @object
end

- (Object) root

Returns the value of attribute root



117
118
119
# File 'lib/active_model/serializer.rb', line 117

def root
  @root
end

- (Object) scope

Returns the value of attribute scope



117
118
119
# File 'lib/active_model/serializer.rb', line 117

def scope
  @scope
end

Class Method Details

+ (Object) adapter

Deprecated



53
54
55
# File 'lib/active_model/serializer.rb', line 53

def self.adapter
  ActiveModelSerializers::Adapter.lookup(config.adapter)
end

+ (Object) get_serializer_for(klass)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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


87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/active_model/serializer.rb', line 87

def self.get_serializer_for(klass)
  return nil unless config.serializer_lookup_enabled
  serializers_cache.fetch_or_store(klass) do
    # NOTE(beauby): When we drop 1.9.3 support we can lazify the map for perfs.
    serializer_class = serializer_lookup_chain_for(klass).map(&:safe_constantize).find { |x| x && x < ActiveModel::Serializer }

    if serializer_class
      serializer_class
    elsif klass.superclass
      get_serializer_for(klass.superclass)
    end
  end
end

+ (Object) include_directive_from_options(options)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



102
103
104
105
106
107
108
109
110
# File 'lib/active_model/serializer.rb', line 102

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

+ (Object) serialization_adapter_instance

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



113
114
115
# File 'lib/active_model/serializer.rb', line 113

def self.serialization_adapter_instance
  @serialization_adapter_instance ||= ActiveModelSerializers::Adapter::Attributes
end

+ (ActiveModel::Serializer) serializer_for(resource, options = {})

Returns Preferentially returns

  1. resource.serializer

  2. ArraySerializer when resource is a collection

  3. options

  4. lookup serializer when resource is a Class

Parameters:

Returns:

  • (ActiveModel::Serializer)

    Preferentially returns

    1. resource.serializer

    2. ArraySerializer when resource is a collection

    3. options

    4. lookup serializer when resource is a Class



41
42
43
44
45
46
47
48
49
# File 'lib/active_model/serializer.rb', line 41

def self.serializer_for(resource, options = {})
  if resource.respond_to?(:serializer_class)
    resource.serializer_class
  elsif resource.respond_to?(:to_ary)
    config.collection_serializer
  else
    options.fetch(:serializer) { get_serializer_for(resource.class) }
  end
end

+ (Object) serializer_lookup_chain_for(klass)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/active_model/serializer.rb', line 62

def self.serializer_lookup_chain_for(klass)
  chain = []

  resource_class_name = klass.name.demodulize
  resource_namespace = klass.name.deconstantize
  serializer_class_name = "#{resource_class_name}Serializer"

  chain.push("#{name}::#{serializer_class_name}") if self != ActiveModel::Serializer
  chain.push("#{resource_namespace}::#{serializer_class_name}")

  chain
end

+ (Object) serializers_cache

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



77
78
79
# File 'lib/active_model/serializer.rb', line 77

def self.serializers_cache
  @serializers_cache ||= ThreadSafe::Cache.new
end

Instance Method Details

- (Object) as_json(adapter_opts = nil)

TODO: When moving attributes adapter logic here, @see #serializable_hash So that the below is true:

@param options [nil, Hash] The same valid options passed to `as_json`
   (:root, :only, :except, :methods, and :include).
The default for `root` is nil.
The default value for include_root is false. You can change it to true if the given
JSON string includes a single root node.

See Also:



185
186
187
# File 'lib/active_model/serializer.rb', line 185

def as_json(adapter_opts = nil)
  serializable_hash(adapter_opts)
end

- (Object) json_key

Used by adapter as resource root.



190
191
192
# File 'lib/active_model/serializer.rb', line 190

def json_key
  root || _type || object.class.model_name.to_s.underscore
end

- (Object) read_attribute_for_serialization(attr)



194
195
196
197
198
199
200
# File 'lib/active_model/serializer.rb', line 194

def read_attribute_for_serialization(attr)
  if respond_to?(attr)
    send(attr)
  else
    object.read_attribute_for_serialization(attr)
  end
end

- (Object) relationship_value_for(association, adapter_options, adapter_instance)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/active_model/serializer.rb', line 215

def relationship_value_for(association, adapter_options, adapter_instance)
  return association.options[:virtual_value] if association.options[:virtual_value]
  association_serializer = association.serializer
  association_object = association_serializer && association_serializer.object
  return unless association_object

  relationship_value = association_serializer.serializable_hash(adapter_options, {}, adapter_instance)

  if association.options[:polymorphic] && relationship_value
    polymorphic_type = association_object.class.name.underscore
    relationship_value = { type: polymorphic_type, polymorphic_type.to_sym => relationship_value }
  end

  relationship_value
end

- (Object) resource_relationships(adapter_options, options, adapter_instance)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



203
204
205
206
207
208
209
210
211
212
# File 'lib/active_model/serializer.rb', line 203

def resource_relationships(adapter_options, options, adapter_instance)
  relationships = {}
  include_directive = options.fetch(:include_directive)
  associations(include_directive).each do |association|
    adapter_opts = adapter_options.merge(include_directive: include_directive[association.key])
    relationships[association.key] ||= relationship_value_for(association, adapter_opts, adapter_instance)
  end

  relationships
end

- (Hash) serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance) Also known as: to_hash, to_h

associations, similar to how ActiveModel::Serializers::JSON is used in ActiveRecord::Base.

TODO: Include ActiveModel::Serializers::JSON. So that the below is true:

@param options [nil, Hash] The same valid options passed to `serializable_hash`
   (:only, :except, :methods, and :include).

  See
  https://github.com/rails/rails/blob/v5.0.0.beta2/activemodel/lib/active_model/serializers/json.rb#L17-L101
  https://github.com/rails/rails/blob/v5.0.0.beta2/activemodel/lib/active_model/serialization.rb#L85-L123
  https://github.com/rails/rails/blob/v5.0.0.beta2/activerecord/lib/active_record/serialization.rb#L11-L17
  https://github.com/rails/rails/blob/v5.0.0.beta2/activesupport/lib/active_support/core_ext/object/json.rb#L147-L162

@example
  # The :only and :except options can be used to limit the attributes included, and work
  # similar to the attributes method.
  serializer.as_json(only: [:id, :name])
  serializer.as_json(except: [:id, :created_at, :age])

  # To include the result of some method calls on the model use :methods:
  serializer.as_json(methods: :permalink)

  # To include associations use :include:
  serializer.as_json(include: :posts)
  # Second level and higher order associations work as well:
  serializer.as_json(include: { posts: { include: { comments: { only: :body } }, only: :title } })

Returns:

  • (Hash)

    containing the attributes and first level



166
167
168
169
170
171
172
173
# File 'lib/active_model/serializer.rb', line 166

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)
  cached_attributes = adapter_options[:cached_attributes] ||= {}
  resource = fetch_attributes(options[:fields], cached_attributes, adapter_instance)
  relationships = resource_relationships(adapter_options, options, adapter_instance)
  resource.merge(relationships)
end

- (Boolean) success?

Returns:

  • (Boolean)


134
135
136
# File 'lib/active_model/serializer.rb', line 134

def success?
  true
end