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.15'.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
attributes
ofobject
as presented by the serializer. - #attributes_hash(_adapter_options, options, adapter_instance) ⇒ Object private
-
#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
-
#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:
1. class name appended with "Serializer"
2. try again with superclass, if present
3. 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
-
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 |