Move adapter cache properties to class level (where they belong).

This commit is contained in:
Benjamin Fleischer
2016-06-04 14:37:51 -05:00
parent 516e7da8ff
commit 913f396bb1
6 changed files with 84 additions and 67 deletions

View File

@@ -109,6 +109,10 @@ module ActiveModel
end
end
def self.serialization_adapter_instance
@serialization_adapter_instance ||= ActiveModelSerializers::Adapter::Attributes
end
attr_accessor :object, :root, :scope
# `scope_name` is set as :current_user by default in the controller.
@@ -163,8 +167,7 @@ module ActiveModel
def serializable_hash(adapter_opts = nil)
adapter_opts ||= {}
adapter_opts = { include: '*' }.merge!(adapter_opts)
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(self, adapter_opts)
serialize(adapter_opts, {}, adapter_instance)
serialize(adapter_opts)
end
alias to_hash serializable_hash
alias to_h serializable_hash
@@ -197,7 +200,7 @@ module ActiveModel
end
# @api private
def serialize(adapter_options, options, adapter_instance)
def serialize(adapter_options, options = {}, adapter_instance = self.class.serialization_adapter_instance)
options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options)
cached_attributes = adapter_options[:cached_attributes] ||= {}
resource = cached_attributes(options[:fields], cached_attributes, adapter_instance)

View File

@@ -318,7 +318,7 @@ module ActiveModel
parts = []
parts << object_cache_key
parts << adapter_instance.cached_name
parts << adapter_instance.cache_key
parts << self.class._cache_digest unless self.class._skip_digest?
@cache_key = parts.join('/')
end

View File

@@ -51,6 +51,10 @@ module ActiveModelSerializers
self
end
def registered_name(adapter_class)
ADAPTER_MAP.key adapter_class
end
# @param adapter [String, Symbol, Class] name to fetch adapter by
# @return [ActiveModelSerializers::Adapter] subclass of Adapter
# @raise [UnknownAdapterError]

View File

@@ -8,6 +8,40 @@ module ActiveModelSerializers
ActiveModelSerializers::Adapter.register(subclass)
end
# Sets the default transform for the adapter.
#
# @return [Symbol] the default transform for the adapter
def self.default_key_transform
:unaltered
end
# Determines the transform to use in order of precedence:
# adapter option, global config, adapter default.
#
# @param options [Object]
# @return [Symbol] the transform to use
def self.transform(options)
return options[:key_transform] if options && options[:key_transform]
ActiveModelSerializers.config.key_transform || default_key_transform
end
# Transforms the casing of the supplied value.
#
# @param value [Object] the value to be transformed
# @param options [Object] serializable resource options
# @return [Symbol] the default transform for the adapter
def self.transform_key_casing!(value, options)
KeyTransform.send(transform(options), value)
end
def self.cache_key
@cache_key ||= ActiveModelSerializers::Adapter.registered_name(self)
end
def self.fragment_cache(cached_hash, non_cached_hash)
non_cached_hash.merge cached_hash
end
attr_reader :serializer, :instance_options
def initialize(serializer, options = {})
@@ -15,10 +49,6 @@ module ActiveModelSerializers
@instance_options = options
end
def cached_name
@cached_name ||= self.class.name.demodulize.underscore
end
# Subclasses that implement this method must first call
# options = serialization_options(options)
def serializable_hash(_options = nil)
@@ -29,8 +59,12 @@ module ActiveModelSerializers
serializable_hash(options)
end
def cache_key
self.class.cache_key
end
def fragment_cache(cached_hash, non_cached_hash)
non_cached_hash.merge cached_hash
self.class.fragment_cache(cached_hash, non_cached_hash)
end
private
@@ -44,34 +78,6 @@ module ActiveModelSerializers
def root
serializer.json_key.to_sym if serializer.json_key
end
class << self
# Sets the default transform for the adapter.
#
# @return [Symbol] the default transform for the adapter
def default_key_transform
:unaltered
end
# Determines the transform to use in order of precedence:
# adapter option, global config, adapter default.
#
# @param options [Object]
# @return [Symbol] the transform to use
def transform(options)
return options[:key_transform] if options && options[:key_transform]
ActiveModelSerializers.config.key_transform || default_key_transform
end
# Transforms the casing of the supplied value.
#
# @param value [Object] the value to be transformed
# @param options [Object] serializable resource options
# @return [Symbol] the default transform for the adapter
def transform_key_casing!(value, options)
KeyTransform.send(transform(options), value)
end
end
end
end
end

View File

@@ -31,16 +31,27 @@ module ActiveModelSerializers
autoload :Error
autoload :Deserialization
def self.default_key_transform
:dash
end
def self.fragment_cache(cached_hash, non_cached_hash, root = true)
core_cached = cached_hash.first
core_non_cached = non_cached_hash.first
no_root_cache = cached_hash.delete_if { |key, _value| key == core_cached[0] }
no_root_non_cache = non_cached_hash.delete_if { |key, _value| key == core_non_cached[0] }
cached_resource = (core_cached[1]) ? core_cached[1].deep_merge(core_non_cached[1]) : core_non_cached[1]
hash = root ? { root => cached_resource } : cached_resource
hash.deep_merge no_root_non_cache.deep_merge no_root_cache
end
def initialize(serializer, options = {})
super
@include_directive = JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true)
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
end
def self.default_key_transform
:dash
end
# {http://jsonapi.org/format/#crud Requests are transactional, i.e. success or failure}
# {http://jsonapi.org/format/#document-top-level data and errors MUST NOT coexist in the same document.}
def serializable_hash(*)
@@ -52,6 +63,11 @@ module ActiveModelSerializers
self.class.transform_key_casing!(document, instance_options)
end
def fragment_cache(cached_hash, non_cached_hash)
root = !instance_options.include?(:include)
self.class.fragment_cache(cached_hash, non_cached_hash, root)
end
# {http://jsonapi.org/format/#document-top-level Primary data}
# definition:
# ☐ toplevel_data (required)
@@ -174,18 +190,6 @@ module ActiveModelSerializers
hash
end
def fragment_cache(cached_hash, non_cached_hash)
root = false if instance_options.include?(:include)
core_cached = cached_hash.first
core_non_cached = non_cached_hash.first
no_root_cache = cached_hash.delete_if { |key, _value| key == core_cached[0] }
no_root_non_cache = non_cached_hash.delete_if { |key, _value| key == core_non_cached[0] }
cached_resource = (core_cached[1]) ? core_cached[1].deep_merge(core_non_cached[1]) : core_non_cached[1]
hash = root ? { root => cached_resource } : cached_resource
hash.deep_merge no_root_non_cache.deep_merge no_root_cache
end
protected
attr_reader :fieldset