Class: ActiveModel::Serializer
- Inherits:
-
Object
- Object
- ActiveModel::Serializer
- Extended by:
- ActiveModelSerializers::Deprecate, ActiveSupport::Autoload
- Includes:
- Caching, ActiveSupport::Configurable
- Defined in:
- lib/active_model/serializer.rb,
lib/active_model/serializer/link.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/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/lazy_association.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/has_many_reflection.rb,
lib/active_model/serializer/belongs_to_reflection.rb,
lib/active_model/serializer/collection_serializer.rb
Direct Known Subclasses
Defined Under Namespace
Modules: Adapter, Caching, Lint Classes: ArraySerializer, Association, Attribute, BelongsToReflection, CollectionSerializer, ErrorSerializer, ErrorsSerializer, Field, Fieldset, HasManyReflection, HasOneReflection, LazyAssociation, Link, Null, Reflection
Constant Summary collapse
- SERIALIZABLE_HASH_VALID_KEYS =
[:only, :except, :methods, :include, :root].freeze
- VERSION =
'0.10.13'.freeze
- UndefinedCacheKey =
Class.new(StandardError)
Constants included from Caching
Instance Attribute Summary collapse
-
#object ⇒ Object
END SERIALIZER MACROS.
-
#root ⇒ Object
END SERIALIZER MACROS.
-
#scope ⇒ Object
END SERIALIZER MACROS.
Class Method Summary collapse
-
._attributes ⇒ Array<Symbol>
Key names of declared attributes.
-
.adapter ⇒ Object
Deprecated.
- .attribute(attr, options = {}, &block) ⇒ Object
- .attributes(*attrs) ⇒ Object
- .belongs_to(name, options = {}, &block) ⇒ void
-
.get_serializer_for(klass, namespace = nil) ⇒ Object
private
Find a serializer from a class and caches the lookup.
- .has_many(name, options = {}, &block) ⇒ void
- .has_one(name, options = {}, &block) ⇒ void
- .include_directive_from_options(options) ⇒ Object private
- .inherited(base) ⇒ Object
-
.link(name, *args, &block) ⇒ Object
Define a link on a serializer.
-
.meta(value = nil, &block) ⇒ Object
Set the JSON API meta attribute of a serializer.
- .serialization_adapter_instance ⇒ Object private
-
.serializer_for(resource_or_class, 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.
-
.type(type) ⇒ Object
Set the JSON API type of a serializer.
Instance Method Summary collapse
- #as_json(adapter_opts = nil) ⇒ Object
- #associations(include_directive = ActiveModelSerializers.default_include_directive, include_slice = nil) ⇒ Enumerator<Association>
- #associations_hash(adapter_options, options, adapter_instance) ⇒ Object private
-
#attributes(requested_attrs = nil, reload = false) ⇒ Object
Return the
attributesofobjectas presented by the serializer. - #attributes_hash(_adapter_options, options, adapter_instance) ⇒ Object private
-
#initialize(object, options = {}) ⇒ Serializer
constructor
scope_nameis set as :current_user by default in the controller. -
#json_key ⇒ Object
Used by adapter as resource root.
- #read_attribute_for_serialization(attr) ⇒ Object
-
#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
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.
319 320 321 322 323 324 325 326 327 328 |
# File 'lib/active_model/serializer.rb', line 319 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
END SERIALIZER MACROS
314 315 316 |
# File 'lib/active_model/serializer.rb', line 314 def object @object end |
#root ⇒ Object
END SERIALIZER MACROS
314 315 316 |
# File 'lib/active_model/serializer.rb', line 314 def root @root end |
#scope ⇒ Object
END SERIALIZER MACROS
314 315 316 |
# File 'lib/active_model/serializer.rb', line 314 def scope @scope end |
Class Method Details
._attributes ⇒ Array<Symbol>
Returns Key names of declared attributes.
197 198 199 |
# File 'lib/active_model/serializer.rb', line 197 def self._attributes _attributes_data.keys end |
.adapter ⇒ Object
Deprecated
56 57 58 |
# File 'lib/active_model/serializer.rb', line 56 def self.adapter ActiveModelSerializers::Adapter.lookup(config.adapter) end |
.attribute(attr, options = {}, &block) ⇒ Object
226 227 228 229 |
# File 'lib/active_model/serializer.rb', line 226 def self.attribute(attr, = {}, &block) key = .fetch(:key, attr) _attributes_data[key] = Attribute.new(attr, , block) end |
.attributes(*attrs) ⇒ Object
206 207 208 209 210 211 212 |
# File 'lib/active_model/serializer.rb', line 206 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) ⇒ void
This method returns an undefined value.
249 250 251 |
# File 'lib/active_model/serializer.rb', line 249 def self.belongs_to(name, = {}, &block) associate(BelongsToReflection.new(name, , block)) 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:
- class name appended with "Serializer"
- try again with superclass, if present
- nil
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/active_model/serializer.rb', line 84 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, namespace) else nil # No serializer found end end end |
.has_many(name, options = {}, &block) ⇒ void
This method returns an undefined value.
238 239 240 |
# File 'lib/active_model/serializer.rb', line 238 def self.has_many(name, = {}, &block) # rubocop:disable Style/PredicateName associate(HasManyReflection.new(name, , block)) end |
.has_one(name, options = {}, &block) ⇒ void
This method returns an undefined value.
260 261 262 |
# File 'lib/active_model/serializer.rb', line 260 def self.has_one(name, = {}, &block) # rubocop:disable Style/PredicateName associate(HasOneReflection.new(name, , block)) 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.
104 105 106 107 108 109 110 111 112 |
# File 'lib/active_model/serializer.rb', line 104 def self.() if [:include_directive] [:include_directive] elsif [:include] JSONAPI::IncludeDirective.new([:include], allow_wildcard: true) else ActiveModelSerializers.default_include_directive end end |
.inherited(base) ⇒ Object
188 189 190 191 192 193 |
# File 'lib/active_model/serializer.rb', line 188 def self.inherited(base) super base._attributes_data = _attributes_data.dup base._reflections = _reflections.dup base._links = _links.dup end |
.link(name, *args, &block) ⇒ Object
Define a link on a serializer.
285 286 287 288 289 290 |
# File 'lib/active_model/serializer.rb', line 285 def self.link(name, *args, &block) = args. # For compatibility with the use case of passing link directly as string argument # without block, we are creating a wrapping block _links[name] = Link.new(name, , block || ->(_serializer) { args.first }) end |
.meta(value = nil, &block) ⇒ Object
Set the JSON API meta attribute of a serializer.
300 301 302 |
# File 'lib/active_model/serializer.rb', line 300 def self.(value = nil, &block) self. = block || value 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.
115 116 117 |
# File 'lib/active_model/serializer.rb', line 115 def self.serialization_adapter_instance @serialization_adapter_instance ||= ActiveModelSerializers::Adapter::Attributes end |
.serializer_for(resource_or_class, options = {}) ⇒ ActiveModel::Serializer
Returns Preferentially returns
- resource.serializer_class
- ArraySerializer when resource is a collection
- options
- lookup serializer when resource is a Class.
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/active_model/serializer.rb', line 43 def self.serializer_for(resource_or_class, = {}) 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 .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.
65 66 67 68 69 70 |
# File 'lib/active_model/serializer.rb', line 65 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.
74 75 76 |
# File 'lib/active_model/serializer.rb', line 74 def self.serializers_cache @serializers_cache ||= Concurrent::Map.new end |
.type(type) ⇒ Object
Set the JSON API type of a serializer.
308 309 310 |
# File 'lib/active_model/serializer.rb', line 308 def self.type(type) self._type = type && type.to_s end |
Instance Method Details
#as_json(adapter_opts = nil) ⇒ Object
380 381 382 |
# File 'lib/active_model/serializer.rb', line 380 def as_json(adapter_opts = nil) serializable_hash(adapter_opts) end |
#associations(include_directive = ActiveModelSerializers.default_include_directive, include_slice = nil) ⇒ Enumerator<Association>
348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/active_model/serializer.rb', line 348 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, , include_slice) y.yield association end end end |
#associations_hash(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.
414 415 416 417 418 419 420 421 |
# File 'lib/active_model/serializer.rb', line 414 def associations_hash(, , adapter_instance) include_directive = .fetch(:include_directive) include_slice = [:include_slice] associations(include_directive, include_slice).each_with_object({}) do |association, relationships| adapter_opts = .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) ⇒ Object
Return the attributes of object as presented
by the serializer.
336 337 338 339 340 341 342 343 |
# File 'lib/active_model/serializer.rb', line 336 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) ⇒ 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.
403 404 405 406 407 408 409 410 411 |
# File 'lib/active_model/serializer.rb', line 403 def attributes_hash(, , adapter_instance) if self.class.cache_enabled? fetch_attributes([:fields], [:cached_attributes] || {}, adapter_instance) elsif self.class.fragment_cache_enabled? fetch_attributes_fragment(adapter_instance, [:cached_attributes] || {}) else attributes([:fields], true) end end |
#json_key ⇒ Object
Used by adapter as resource root.
385 386 387 388 389 390 391 392 |
# File 'lib/active_model/serializer.rb', line 385 def json_key root || _type || begin object.class.model_name.to_s.underscore rescue ArgumentError 'anonymous_object' end end |
#read_attribute_for_serialization(attr) ⇒ Object
394 395 396 397 398 399 400 |
# File 'lib/active_model/serializer.rb', line 394 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) ⇒ Hash Also known as: to_hash, to_h
associations, similar to how ActiveModel::Serializers::JSON is used in ActiveRecord::Base.
366 367 368 369 370 371 372 373 374 375 |
# File 'lib/active_model/serializer.rb', line 366 def serializable_hash( = nil, = {}, adapter_instance = self.class.serialization_adapter_instance) ||= {} [:include_directive] ||= ActiveModel::Serializer.() if (fieldset = [:fieldset]) [:fields] = fieldset.fields_for(json_key) end resource = attributes_hash(, , adapter_instance) relationships = associations_hash(, , adapter_instance) resource.merge(relationships) end |
#success? ⇒ Boolean
330 331 332 |
# File 'lib/active_model/serializer.rb', line 330 def success? true end |