Class: ActiveModel::Serializer
- Inherits:
-
Object
- Object
- ActiveModel::Serializer
- Extended by:
- ActiveModelSerializers::Deprecate, ActiveSupport::Autoload
- Includes:
- Caching
- 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.16'.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_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.
322 323 324 325 326 327 328 329 330 331 |
# File 'lib/active_model/serializer.rb', line 322 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
317 318 319 |
# File 'lib/active_model/serializer.rb', line 317 def object @object end |
#root ⇒ Object
END SERIALIZER MACROS
317 318 319 |
# File 'lib/active_model/serializer.rb', line 317 def root @root end |
#scope ⇒ Object
END SERIALIZER MACROS
317 318 319 |
# File 'lib/active_model/serializer.rb', line 317 def scope @scope end |
Class Method Details
._attributes ⇒ Array<Symbol>
Returns Key names of declared attributes.
200 201 202 |
# File 'lib/active_model/serializer.rb', line 200 def self._attributes _attributes_data.keys end |
.adapter ⇒ Object
Deprecated
58 59 60 |
# File 'lib/active_model/serializer.rb', line 58 def self.adapter ActiveModelSerializers::Adapter.lookup(config.adapter) end |
.attribute(attr, options = {}, &block) ⇒ Object
229 230 231 232 |
# File 'lib/active_model/serializer.rb', line 229 def self.attribute(attr, = {}, &block) key = .fetch(:key, attr) _attributes_data[key] = Attribute.new(attr, , block) end |
.attributes(*attrs) ⇒ Object
209 210 211 212 213 214 215 |
# File 'lib/active_model/serializer.rb', line 209 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.
252 253 254 |
# File 'lib/active_model/serializer.rb', line 252 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
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/active_model/serializer.rb', line 86 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.
241 242 243 |
# File 'lib/active_model/serializer.rb', line 241 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.
263 264 265 |
# File 'lib/active_model/serializer.rb', line 263 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.
106 107 108 109 110 111 112 113 114 |
# File 'lib/active_model/serializer.rb', line 106 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
190 191 192 193 194 195 196 |
# File 'lib/active_model/serializer.rb', line 190 def self.inherited(base) super base._attributes_data = _attributes_data.dup base._reflections = _reflections.dup base._links = _links.dup base.config = ActiveSupport::InheritableOptions.new(config) end |
.link(name, *args, &block) ⇒ Object
Define a link on a serializer.
288 289 290 291 292 293 |
# File 'lib/active_model/serializer.rb', line 288 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.
303 304 305 |
# File 'lib/active_model/serializer.rb', line 303 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.
117 118 119 |
# File 'lib/active_model/serializer.rb', line 117 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.
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/active_model/serializer.rb', line 45 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.
67 68 69 70 71 72 |
# File 'lib/active_model/serializer.rb', line 67 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.
76 77 78 |
# File 'lib/active_model/serializer.rb', line 76 def self.serializers_cache @serializers_cache ||= Concurrent::Map.new end |
.type(type) ⇒ Object
Set the JSON API type of a serializer.
311 312 313 |
# File 'lib/active_model/serializer.rb', line 311 def self.type(type) self._type = type && type.to_s end |
Instance Method Details
#as_json(adapter_opts = nil) ⇒ Object
383 384 385 |
# File 'lib/active_model/serializer.rb', line 383 def as_json(adapter_opts = nil) serializable_hash(adapter_opts) end |
#associations(include_directive = ActiveModelSerializers.default_include_directive, include_slice = nil) ⇒ Enumerator<Association>
351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/active_model/serializer.rb', line 351 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.
417 418 419 420 421 422 423 424 |
# File 'lib/active_model/serializer.rb', line 417 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.
339 340 341 342 343 344 345 346 |
# File 'lib/active_model/serializer.rb', line 339 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.
406 407 408 409 410 411 412 413 414 |
# File 'lib/active_model/serializer.rb', line 406 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.
388 389 390 391 392 393 394 395 |
# File 'lib/active_model/serializer.rb', line 388 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
397 398 399 400 401 402 403 |
# File 'lib/active_model/serializer.rb', line 397 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.
369 370 371 372 373 374 375 376 377 378 |
# File 'lib/active_model/serializer.rb', line 369 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
333 334 335 |
# File 'lib/active_model/serializer.rb', line 333 def success? true end |