Class: ActiveModel::Serializer
- Inherits:
-
Object
- Object
- ActiveModel::Serializer
- 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/lint.rb,
lib/active_model/serializer/null.rb,
lib/active_model/serializer/field.rb,
lib/active_model/serializer/adapter.rb,
lib/active_model/serializer/version.rb,
lib/active_model/serializer/fieldset.rb,
lib/active_model/serializer/attribute.rb,
lib/active_model/serializer/reflection.rb,
lib/active_model/serializer/association.rb,
lib/active_model/serializer/adapter/base.rb,
lib/active_model/serializer/adapter/json.rb,
lib/active_model/serializer/adapter/null.rb,
lib/active_model/serializer/concerns/meta.rb,
lib/active_model/serializer/concerns/type.rb,
lib/active_model/serializer/concerns/links.rb,
lib/active_model/serializer/adapter/json_api.rb,
lib/active_model/serializer/array_serializer.rb,
lib/active_model/serializer/concerns/caching.rb,
lib/active_model/serializer/error_serializer.rb,
lib/active_model/serializer/errors_serializer.rb,
lib/active_model/serializer/adapter/attributes.rb,
lib/active_model/serializer/has_one_reflection.rb,
lib/active_model/serializer/concerns/attributes.rb,
lib/active_model/serializer/has_many_reflection.rb,
lib/active_model/serializer/singular_reflection.rb,
lib/active_model/serializer/belongs_to_reflection.rb,
lib/active_model/serializer/collection_reflection.rb,
lib/active_model/serializer/collection_serializer.rb,
lib/active_model/serializer/concerns/associations.rb,
lib/active_model/serializer/concerns/configuration.rb
Direct Known Subclasses
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 collapse
- SERIALIZABLE_HASH_VALID_KEYS =
[:only, :except, :methods, :include, :root].freeze
- VERSION =
'0.10.8'.freeze
- UndefinedCacheKey =
Class.new(StandardError)
Constants included from Caching
Instance Attribute Summary collapse
-
#object ⇒ Object
Returns the value of attribute object.
-
#root ⇒ Object
Returns the value of attribute root.
-
#scope ⇒ Object
Returns the value of attribute scope.
Class Method Summary collapse
-
.adapter ⇒ Object
Deprecated.
-
.get_serializer_for(klass, namespace = nil) ⇒ Object
private
Find a serializer from a class and caches the lookup.
- .include_directive_from_options(options) ⇒ Object private
- .serialization_adapter_instance ⇒ Object private
-
.serializer_for(resource, options = {}) ⇒ ActiveModel::Serializer
Preferentially returns 1.
- .serializer_lookup_chain_for(klass, namespace = nil) ⇒ Object private
-
.serializers_cache ⇒ Object
Used to cache serializer name => serializer class when looked up by Serializer.get_serializer_for.
Instance Method Summary collapse
-
#as_json(adapter_opts = nil) ⇒ Object
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).
-
#initialize(object, options = {}) ⇒ Serializer
constructor
‘scope_name` is set as :current_user by default in the controller.
-
#json_key ⇒ Object
Used by adapter as resource root.
- #read_attribute_for_serialization(attr) ⇒ Object
- #relationship_value_for(association, adapter_options, adapter_instance) ⇒ Object private
- #resource_relationships(adapter_options, options, adapter_instance) ⇒ Object private
-
#serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance) ⇒ Hash
(also: #to_hash, #to_h)
associations, similar to how ActiveModel::Serializers::JSON is used in ActiveRecord::Base.
- #success? ⇒ Boolean
Methods included from ActiveModelSerializers::Deprecate
delegate_and_deprecate, deprecate
Methods included from Caching
#cache_key, #expand_cache_key, #fetch, #fetch_attributes, #fetch_attributes_fragment, #object_cache_key, #serializer_class
Methods included from Associations
Constructor Details
#initialize(object, options = {}) ⇒ Serializer
‘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
.
119 120 121 122 123 124 125 126 127 128 |
# File 'lib/active_model/serializer.rb', line 119 def initialize(object, = {}) self.object = object self. = self.root = [:root] self.scope = [:scope] return if !(scope_name = [:scope_name]) || respond_to?(scope_name) define_singleton_method scope_name, -> { scope } end |
Instance Attribute Details
#object ⇒ Object
Returns the value of attribute object.
114 115 116 |
# File 'lib/active_model/serializer.rb', line 114 def object @object end |
#root ⇒ Object
Returns the value of attribute root.
114 115 116 |
# File 'lib/active_model/serializer.rb', line 114 def root @root end |
#scope ⇒ Object
Returns the value of attribute scope.
114 115 116 |
# File 'lib/active_model/serializer.rb', line 114 def scope @scope end |
Class Method Details
.adapter ⇒ Object
Deprecated
53 54 55 |
# File 'lib/active_model/serializer.rb', line 53 def self.adapter ActiveModelSerializers::Adapter.lookup(config.adapter) end |
.get_serializer_for(klass, namespace = nil) ⇒ Object
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
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/active_model/serializer.rb', line 81 def self.get_serializer_for(klass, namespace = nil) return nil unless config.serializer_lookup_enabled cache_key = ActiveSupport::Cache.(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) end end end |
.include_directive_from_options(options) ⇒ Object
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.
99 100 101 102 103 104 105 106 107 |
# File 'lib/active_model/serializer.rb', line 99 def self.() if [:include_directive] [:include_directive] elsif [:include] JSONAPI::IncludeDirective.new([:include], allow_wildcard: true) else ActiveModelSerializers.default_include_directive end end |
.serialization_adapter_instance ⇒ Object
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.
110 111 112 |
# File 'lib/active_model/serializer.rb', line 110 def self.serialization_adapter_instance @serialization_adapter_instance ||= ActiveModelSerializers::Adapter::Attributes end |
.serializer_for(resource, options = {}) ⇒ ActiveModel::Serializer
Returns Preferentially returns
-
resource.serializer
-
ArraySerializer when resource is a collection
-
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, = {}) if resource.respond_to?(:serializer_class) resource.serializer_class elsif resource.respond_to?(:to_ary) config.collection_serializer else .fetch(:serializer) { get_serializer_for(resource.class, [:namespace]) } end end |
.serializer_lookup_chain_for(klass, namespace = nil) ⇒ Object
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 |
# File 'lib/active_model/serializer.rb', line 62 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 ⇒ Object
Used to cache serializer name => serializer class when looked up by Serializer.get_serializer_for.
71 72 73 |
# File 'lib/active_model/serializer.rb', line 71 def self.serializers_cache @serializers_cache ||= ThreadSafe::Cache.new end |
Instance Method Details
#as_json(adapter_opts = nil) ⇒ Object
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.
181 182 183 |
# File 'lib/active_model/serializer.rb', line 181 def as_json(adapter_opts = nil) serializable_hash(adapter_opts) end |
#json_key ⇒ Object
Used by adapter as resource root.
186 187 188 |
# File 'lib/active_model/serializer.rb', line 186 def json_key root || _type || object.class.model_name.to_s.underscore end |
#read_attribute_for_serialization(attr) ⇒ Object
190 191 192 193 194 195 196 |
# File 'lib/active_model/serializer.rb', line 190 def read_attribute_for_serialization(attr) if respond_to?(attr) send(attr) else object.read_attribute_for_serialization(attr) end end |
#relationship_value_for(association, adapter_options, adapter_instance) ⇒ Object
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.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/active_model/serializer.rb', line 211 def relationship_value_for(association, , adapter_instance) return association.[:virtual_value] if association.[:virtual_value] association_serializer = association.serializer association_object = association_serializer && association_serializer.object return unless association_object relationship_value = association_serializer.serializable_hash(, {}, adapter_instance) if association.[: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 |
#resource_relationships(adapter_options, options, adapter_instance) ⇒ Object
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.
199 200 201 202 203 204 205 206 207 208 |
# File 'lib/active_model/serializer.rb', line 199 def resource_relationships(, , adapter_instance) relationships = {} include_directive = .fetch(:include_directive) associations(include_directive).each do |association| adapter_opts = .merge(include_directive: include_directive[association.key]) relationships[association.key] ||= relationship_value_for(association, adapter_opts, adapter_instance) end relationships end |
#serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance) ⇒ Hash 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 } })
162 163 164 165 166 167 168 169 |
# File 'lib/active_model/serializer.rb', line 162 def serializable_hash( = nil, = {}, adapter_instance = self.class.serialization_adapter_instance) ||= {} [:include_directive] ||= ActiveModel::Serializer.() cached_attributes = [:cached_attributes] ||= {} resource = fetch_attributes([:fields], cached_attributes, adapter_instance) relationships = resource_relationships(, , adapter_instance) resource.merge(relationships) end |
#success? ⇒ Boolean
130 131 132 |
# File 'lib/active_model/serializer.rb', line 130 def success? true end |