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/meta.rb,
lib/active_model/serializer/null.rb,
lib/active_model/serializer/type.rb,
lib/active_model/serializer/field.rb,
lib/active_model/serializer/links.rb,
lib/active_model/serializer/adapter.rb,
lib/active_model/serializer/caching.rb,
lib/active_model/serializer/version.rb,
lib/active_model/serializer/fieldset.rb,
lib/active_model/serializer/attribute.rb,
lib/active_model/serializer/attributes.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/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/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
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
- UndefinedCacheKey =
Class.new(StandardError)
- VERSION =
'0.10.1'.freeze
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) ⇒ 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) ⇒ 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, #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.
122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/active_model/serializer.rb', line 122 def initialize(object, = {}) self.object = object self. = self.root = [:root] self.scope = [:scope] scope_name = [: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 |
#root ⇒ Object
Returns the value of attribute root.
117 118 119 |
# File 'lib/active_model/serializer.rb', line 117 def root @root end |
#scope ⇒ Object
Returns the value of attribute scope.
117 118 119 |
# File 'lib/active_model/serializer.rb', line 117 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) ⇒ 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
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 |
.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.
102 103 104 105 106 107 108 109 110 |
# File 'lib/active_model/serializer.rb', line 102 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.
113 114 115 |
# File 'lib/active_model/serializer.rb', line 113 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) } end end |
.serializer_lookup_chain_for(klass) ⇒ 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 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 |
.serializers_cache ⇒ Object
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
#as_json(adapter_opts = nil) ⇒ Object
TODO: When moving attributes adapter logic here, @see #serializable_hash So that the below is true:
@param [nil, Hash] The same valid 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.
185 186 187 |
# File 'lib/active_model/serializer.rb', line 185 def as_json(adapter_opts = nil) serializable_hash(adapter_opts) end |
#json_key ⇒ Object
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 |
#read_attribute_for_serialization(attr) ⇒ Object
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 |
#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.
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_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.
203 204 205 206 207 208 209 210 211 212 |
# File 'lib/active_model/serializer.rb', line 203 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 [nil, Hash] The same valid 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 } })
166 167 168 169 170 171 172 173 |
# File 'lib/active_model/serializer.rb', line 166 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
134 135 136 |
# File 'lib/active_model/serializer.rb', line 134 def success? true end |