class ActiveModel::Serializer
Constants
- Field
Holds all the meta-data about a field (i.e. attribute or association) as it was specified in the
ActiveModel::Serializer
class. Notice that the field block is evaluated in the context of the serializer.- SERIALIZABLE_HASH_VALID_KEYS
@see
serializable_hash
for more details on these valid keys.- UndefinedCacheKey
- VERSION
Attributes
Public Class Methods
@see ActiveModelSerializers::Adapter.lookup
Deprecated
# File lib/active_model/serializer.rb, line 53 def self.adapter ActiveModelSerializers::Adapter.lookup(config.adapter) end
@api private 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
# 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.expand_cache_key(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
@api private
# File lib/active_model/serializer.rb, line 99 def self.include_directive_from_options(options) if options[:include_directive] options[:include_directive] elsif options[:include] JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true) else ActiveModelSerializers.default_include_directive end end
`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
.
# File lib/active_model/serializer.rb, line 119 def initialize(object, options = {}) self.object = object self.instance_options = options self.root = instance_options[:root] self.scope = instance_options[:scope] return if !(scope_name = instance_options[:scope_name]) || respond_to?(scope_name) define_singleton_method scope_name, -> { scope } end
@api private
# File lib/active_model/serializer.rb, line 110 def self.serialization_adapter_instance @serialization_adapter_instance ||= ActiveModelSerializers::Adapter::Attributes end
@param resource [ActiveRecord::Base, ActiveModelSerializers::Model] @return [ActiveModel::Serializer]
Preferentially returns 1. resource.serializer 2. ArraySerializer when resource is a collection 3. options[:serializer] 4. lookup serializer when resource is a Class
# File lib/active_model/serializer.rb, line 41 def self.serializer_for(resource, options = {}) if resource.respond_to?(:serializer_class) resource.serializer_class elsif resource.respond_to?(:to_ary) config.collection_serializer else options.fetch(:serializer) { get_serializer_for(resource.class, options[:namespace]) } end end
@api private
# 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
Used to cache serializer name => serializer class when looked up by Serializer.get_serializer_for
.
# File lib/active_model/serializer.rb, line 71 def self.serializers_cache @serializers_cache ||= ThreadSafe::Cache.new end
Public Instance Methods
@see serializable_hash
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.
# File lib/active_model/serializer.rb, line 181 def as_json(adapter_opts = nil) serializable_hash(adapter_opts) end
Used by adapter as resource root.
# File lib/active_model/serializer.rb, line 186 def json_key root || _type || object.class.model_name.to_s.underscore end
# 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
@api private
# File lib/active_model/serializer.rb, line 211 def relationship_value_for(association, adapter_options, adapter_instance) return association.options[:virtual_value] if association.options[:virtual_value] association_serializer = association.serializer association_object = association_serializer && association_serializer.object return unless association_object relationship_value = association_serializer.serializable_hash(adapter_options, {}, adapter_instance) if association.options[: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
@api private
# File lib/active_model/serializer.rb, line 199 def resource_relationships(adapter_options, options, adapter_instance) relationships = {} include_directive = options.fetch(:include_directive) associations(include_directive).each do |association| adapter_opts = adapter_options.merge(include_directive: include_directive[association.key]) relationships[association.key] ||= relationship_value_for(association, adapter_opts, adapter_instance) end relationships end
@return [Hash] containing the attributes and first level 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 } })
# File lib/active_model/serializer.rb, line 162 def serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance) adapter_options ||= {} options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options) cached_attributes = adapter_options[:cached_attributes] ||= {} resource = fetch_attributes(options[:fields], cached_attributes, adapter_instance) relationships = resource_relationships(adapter_options, options, adapter_instance) resource.merge(relationships) end
# File lib/active_model/serializer.rb, line 130 def success? true end