mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-24 23:06:50 +00:00
Merge pull request #1766 from bf4/serializer_cleanup_4
Move serialization logic into Serializer and CollectionSerializer
This commit is contained in:
commit
d191342a6c
@ -98,6 +98,22 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @api private
|
||||||
|
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
|
||||||
|
|
||||||
|
# @api private
|
||||||
|
def self.serialization_adapter_instance
|
||||||
|
@serialization_adapter_instance ||= ActiveModelSerializers::Adapter::Attributes
|
||||||
|
end
|
||||||
|
|
||||||
attr_accessor :object, :root, :scope
|
attr_accessor :object, :root, :scope
|
||||||
|
|
||||||
# `scope_name` is set as :current_user by default in the controller.
|
# `scope_name` is set as :current_user by default in the controller.
|
||||||
@ -123,9 +139,7 @@ module ActiveModel
|
|||||||
# associations, similar to how ActiveModel::Serializers::JSON is used
|
# associations, similar to how ActiveModel::Serializers::JSON is used
|
||||||
# in ActiveRecord::Base.
|
# in ActiveRecord::Base.
|
||||||
#
|
#
|
||||||
# TODO: Move to here the Attributes adapter logic for
|
# TODO: Include <tt>ActiveModel::Serializers::JSON</tt>.
|
||||||
# +serializable_hash_for_single_resource(options)+
|
|
||||||
# and include <tt>ActiveModel::Serializers::JSON</tt>.
|
|
||||||
# So that the below is true:
|
# So that the below is true:
|
||||||
# @param options [nil, Hash] The same valid options passed to `serializable_hash`
|
# @param options [nil, Hash] The same valid options passed to `serializable_hash`
|
||||||
# (:only, :except, :methods, and :include).
|
# (:only, :except, :methods, and :include).
|
||||||
@ -149,11 +163,13 @@ module ActiveModel
|
|||||||
# serializer.as_json(include: :posts)
|
# serializer.as_json(include: :posts)
|
||||||
# # Second level and higher order associations work as well:
|
# # Second level and higher order associations work as well:
|
||||||
# serializer.as_json(include: { posts: { include: { comments: { only: :body } }, only: :title } })
|
# serializer.as_json(include: { posts: { include: { comments: { only: :body } }, only: :title } })
|
||||||
def serializable_hash(adapter_opts = nil)
|
def serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance)
|
||||||
adapter_opts ||= {}
|
adapter_options ||= {}
|
||||||
adapter_opts = { include: '*', adapter: :attributes }.merge!(adapter_opts)
|
options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options)
|
||||||
adapter = ActiveModelSerializers::Adapter.create(self, adapter_opts)
|
cached_attributes = adapter_options[:cached_attributes] ||= {}
|
||||||
adapter.serializable_hash(adapter_opts)
|
resource = cached_attributes(options[:fields], cached_attributes, adapter_instance)
|
||||||
|
relationships = resource_relationships(adapter_options, options, adapter_instance)
|
||||||
|
resource.merge(relationships)
|
||||||
end
|
end
|
||||||
alias to_hash serializable_hash
|
alias to_hash serializable_hash
|
||||||
alias to_h serializable_hash
|
alias to_h serializable_hash
|
||||||
@ -185,6 +201,35 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @api private
|
||||||
|
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
|
||||||
|
|
||||||
|
# @api private
|
||||||
|
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
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
attr_accessor :instance_options
|
attr_accessor :instance_options
|
||||||
|
|||||||
@ -318,7 +318,7 @@ module ActiveModel
|
|||||||
|
|
||||||
parts = []
|
parts = []
|
||||||
parts << object_cache_key
|
parts << object_cache_key
|
||||||
parts << adapter_instance.cached_name
|
parts << adapter_instance.cache_key
|
||||||
parts << self.class._cache_digest unless self.class._skip_digest?
|
parts << self.class._cache_digest unless self.class._skip_digest?
|
||||||
@cache_key = parts.join('/')
|
@cache_key = parts.join('/')
|
||||||
end
|
end
|
||||||
|
|||||||
@ -11,22 +11,23 @@ module ActiveModel
|
|||||||
@object = resources
|
@object = resources
|
||||||
@options = options
|
@options = options
|
||||||
@root = options[:root]
|
@root = options[:root]
|
||||||
serializer_context_class = options.fetch(:serializer_context_class, ActiveModel::Serializer)
|
@serializers = serializers_from_resources
|
||||||
@serializers = resources.map do |resource|
|
|
||||||
serializer_class = options.fetch(:serializer) { serializer_context_class.serializer_for(resource) }
|
|
||||||
|
|
||||||
if serializer_class.nil? # rubocop:disable Style/GuardClause
|
|
||||||
fail NoSerializerError, "No serializer found for resource: #{resource.inspect}"
|
|
||||||
else
|
|
||||||
serializer_class.new(resource, options.except(:serializer))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def success?
|
def success?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @api private
|
||||||
|
def serializable_hash(adapter_options, options, adapter_instance)
|
||||||
|
include_directive = ActiveModel::Serializer.include_directive_from_options(adapter_options)
|
||||||
|
adapter_options[:cached_attributes] ||= ActiveModel::Serializer.cache_read_multi(self, adapter_instance, include_directive)
|
||||||
|
adapter_opts = adapter_options.merge(include_directive: include_directive)
|
||||||
|
serializers.map do |serializer|
|
||||||
|
serializer.serializable_hash(adapter_opts, options, adapter_instance)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# TODO: unify naming of root, json_key, and _type. Right now, a serializer's
|
# TODO: unify naming of root, json_key, and _type. Right now, a serializer's
|
||||||
# json_key comes from the root option or the object's model name, by default.
|
# json_key comes from the root option or the object's model name, by default.
|
||||||
# But, if a dev defines a custom `json_key` method with an explicit value,
|
# But, if a dev defines a custom `json_key` method with an explicit value,
|
||||||
@ -59,6 +60,25 @@ module ActiveModel
|
|||||||
protected
|
protected
|
||||||
|
|
||||||
attr_reader :serializers, :options
|
attr_reader :serializers, :options
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def serializers_from_resources
|
||||||
|
serializer_context_class = options.fetch(:serializer_context_class, ActiveModel::Serializer)
|
||||||
|
object.map do |resource|
|
||||||
|
serializer_from_resource(resource, serializer_context_class, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def serializer_from_resource(resource, serializer_context_class, options)
|
||||||
|
serializer_class = options.fetch(:serializer) { serializer_context_class.serializer_for(resource) }
|
||||||
|
|
||||||
|
if serializer_class.nil? # rubocop:disable Style/GuardClause
|
||||||
|
fail NoSerializerError, "No serializer found for resource: #{resource.inspect}"
|
||||||
|
else
|
||||||
|
serializer_class.new(resource, options.except(:serializer))
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -51,6 +51,10 @@ module ActiveModelSerializers
|
|||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def registered_name(adapter_class)
|
||||||
|
ADAPTER_MAP.key adapter_class
|
||||||
|
end
|
||||||
|
|
||||||
# @param adapter [String, Symbol, Class] name to fetch adapter by
|
# @param adapter [String, Symbol, Class] name to fetch adapter by
|
||||||
# @return [ActiveModelSerializers::Adapter] subclass of Adapter
|
# @return [ActiveModelSerializers::Adapter] subclass of Adapter
|
||||||
# @raise [UnknownAdapterError]
|
# @raise [UnknownAdapterError]
|
||||||
|
|||||||
@ -1,65 +1,9 @@
|
|||||||
module ActiveModelSerializers
|
module ActiveModelSerializers
|
||||||
module Adapter
|
module Adapter
|
||||||
class Attributes < Base
|
class Attributes < Base
|
||||||
def initialize(serializer, options = {})
|
|
||||||
super
|
|
||||||
@include_directive =
|
|
||||||
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
|
|
||||||
|
|
||||||
def serializable_hash(options = nil)
|
def serializable_hash(options = nil)
|
||||||
options = serialization_options(options)
|
options = serialization_options(options)
|
||||||
|
serializer.serializable_hash(instance_options, options, self)
|
||||||
if serializer.respond_to?(:each)
|
|
||||||
serializable_hash_for_collection(options)
|
|
||||||
else
|
|
||||||
serializable_hash_for_single_resource(options)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def serializable_hash_for_collection(options)
|
|
||||||
instance_options[:cached_attributes] ||= ActiveModel::Serializer.cache_read_multi(serializer, self, @include_directive)
|
|
||||||
opts = instance_options.merge(include_directive: @include_directive)
|
|
||||||
serializer.map { |s| Attributes.new(s, opts).serializable_hash(options) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def serializable_hash_for_single_resource(options)
|
|
||||||
cached_attributes = instance_options[:cached_attributes] || {}
|
|
||||||
resource = serializer.cached_attributes(options[:fields], cached_attributes, self)
|
|
||||||
relationships = resource_relationships(options)
|
|
||||||
resource.merge(relationships)
|
|
||||||
end
|
|
||||||
|
|
||||||
def resource_relationships(options)
|
|
||||||
relationships = {}
|
|
||||||
serializer.associations(@include_directive).each do |association|
|
|
||||||
relationships[association.key] ||= relationship_value_for(association, options)
|
|
||||||
end
|
|
||||||
|
|
||||||
relationships
|
|
||||||
end
|
|
||||||
|
|
||||||
def relationship_value_for(association, options)
|
|
||||||
return association.options[:virtual_value] if association.options[:virtual_value]
|
|
||||||
return unless association.serializer && association.serializer.object
|
|
||||||
|
|
||||||
opts = instance_options.merge(include_directive: @include_directive[association.key])
|
|
||||||
relationship_value = Attributes.new(association.serializer, opts).serializable_hash(options)
|
|
||||||
|
|
||||||
if association.options[:polymorphic] && relationship_value
|
|
||||||
polymorphic_type = association.serializer.object.class.name.underscore
|
|
||||||
relationship_value = { type: polymorphic_type, polymorphic_type.to_sym => relationship_value }
|
|
||||||
end
|
|
||||||
|
|
||||||
relationship_value
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -8,6 +8,40 @@ module ActiveModelSerializers
|
|||||||
ActiveModelSerializers::Adapter.register(subclass)
|
ActiveModelSerializers::Adapter.register(subclass)
|
||||||
end
|
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
|
attr_reader :serializer, :instance_options
|
||||||
|
|
||||||
def initialize(serializer, options = {})
|
def initialize(serializer, options = {})
|
||||||
@ -15,10 +49,6 @@ module ActiveModelSerializers
|
|||||||
@instance_options = options
|
@instance_options = options
|
||||||
end
|
end
|
||||||
|
|
||||||
def cached_name
|
|
||||||
@cached_name ||= self.class.name.demodulize.underscore
|
|
||||||
end
|
|
||||||
|
|
||||||
# Subclasses that implement this method must first call
|
# Subclasses that implement this method must first call
|
||||||
# options = serialization_options(options)
|
# options = serialization_options(options)
|
||||||
def serializable_hash(_options = nil)
|
def serializable_hash(_options = nil)
|
||||||
@ -29,8 +59,12 @@ module ActiveModelSerializers
|
|||||||
serializable_hash(options)
|
serializable_hash(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cache_key
|
||||||
|
self.class.cache_key
|
||||||
|
end
|
||||||
|
|
||||||
def fragment_cache(cached_hash, non_cached_hash)
|
def fragment_cache(cached_hash, non_cached_hash)
|
||||||
non_cached_hash.merge cached_hash
|
self.class.fragment_cache(cached_hash, non_cached_hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -44,34 +78,6 @@ module ActiveModelSerializers
|
|||||||
def root
|
def root
|
||||||
serializer.json_key.to_sym if serializer.json_key
|
serializer.json_key.to_sym if serializer.json_key
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -31,16 +31,27 @@ module ActiveModelSerializers
|
|||||||
autoload :Error
|
autoload :Error
|
||||||
autoload :Deserialization
|
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 = {})
|
def initialize(serializer, options = {})
|
||||||
super
|
super
|
||||||
@include_directive = JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true)
|
@include_directive = JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true)
|
||||||
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
|
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
|
||||||
end
|
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/#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.}
|
# {http://jsonapi.org/format/#document-top-level data and errors MUST NOT coexist in the same document.}
|
||||||
def serializable_hash(*)
|
def serializable_hash(*)
|
||||||
@ -52,6 +63,11 @@ module ActiveModelSerializers
|
|||||||
self.class.transform_key_casing!(document, instance_options)
|
self.class.transform_key_casing!(document, instance_options)
|
||||||
end
|
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}
|
# {http://jsonapi.org/format/#document-top-level Primary data}
|
||||||
# definition:
|
# definition:
|
||||||
# ☐ toplevel_data (required)
|
# ☐ toplevel_data (required)
|
||||||
@ -174,18 +190,6 @@ module ActiveModelSerializers
|
|||||||
hash
|
hash
|
||||||
end
|
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
|
protected
|
||||||
|
|
||||||
attr_reader :fieldset
|
attr_reader :fieldset
|
||||||
|
|||||||
@ -32,7 +32,7 @@ module ActionController
|
|||||||
|
|
||||||
expected = {
|
expected = {
|
||||||
data: {
|
data: {
|
||||||
id: assigns(:profile).id.to_s,
|
id: @controller.instance_variable_get(:@profile).id.to_s,
|
||||||
type: 'profiles',
|
type: 'profiles',
|
||||||
attributes: {
|
attributes: {
|
||||||
name: 'Name 1',
|
name: 'Name 1',
|
||||||
|
|||||||
@ -103,9 +103,9 @@ module ActionController
|
|||||||
{
|
{
|
||||||
'title' => 'New Post',
|
'title' => 'New Post',
|
||||||
'body' => 'Body',
|
'body' => 'Body',
|
||||||
'id' => assigns(:post).id,
|
'id' => @controller.instance_variable_get(:@post).id,
|
||||||
'comments' => [{ 'id' => 1 }, { 'id' => 2 }],
|
'comments' => [{ 'id' => 1 }, { 'id' => 2 }],
|
||||||
'author' => { 'id' => assigns(:author).id }
|
'author' => { 'id' => @controller.instance_variable_get(:@author).id }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -163,7 +163,7 @@ module ActionController
|
|||||||
end
|
end
|
||||||
expected = {
|
expected = {
|
||||||
data: {
|
data: {
|
||||||
id: assigns(:profile).id.to_s,
|
id: @controller.instance_variable_get(:@profile).id.to_s,
|
||||||
type: 'profiles',
|
type: 'profiles',
|
||||||
attributes: {
|
attributes: {
|
||||||
name: 'Name 1',
|
name: 'Name 1',
|
||||||
@ -246,7 +246,7 @@ module ActionController
|
|||||||
expected = {
|
expected = {
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
id: assigns(:profiles).first.id.to_s,
|
id: @controller.instance_variable_get(:@profiles).first.id.to_s,
|
||||||
type: 'profiles',
|
type: 'profiles',
|
||||||
attributes: {
|
attributes: {
|
||||||
name: 'Name 1',
|
name: 'Name 1',
|
||||||
@ -269,7 +269,7 @@ module ActionController
|
|||||||
expected = {
|
expected = {
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
id: assigns(:profiles).first.id.to_s,
|
id: @controller.instance_variable_get(:@profiles).first.id.to_s,
|
||||||
type: 'profiles',
|
type: 'profiles',
|
||||||
attributes: {
|
attributes: {
|
||||||
name: 'Name 1',
|
name: 'Name 1',
|
||||||
|
|||||||
@ -102,13 +102,13 @@ module ActiveModelSerializers
|
|||||||
|
|
||||||
render_object_with_cache(uncached_author)
|
render_object_with_cache(uncached_author)
|
||||||
key = "#{uncached_author_serializer.class._cache_key}/#{uncached_author_serializer.object.id}-#{uncached_author_serializer.object.updated_at.strftime("%Y%m%d%H%M%S%9N")}"
|
key = "#{uncached_author_serializer.class._cache_key}/#{uncached_author_serializer.object.id}-#{uncached_author_serializer.object.updated_at.strftime("%Y%m%d%H%M%S%9N")}"
|
||||||
key = "#{key}/#{adapter.cached_name}"
|
key = "#{key}/#{adapter.cache_key}"
|
||||||
assert_equal(uncached_author_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
assert_equal(uncached_author_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_default_cache_key_fallback
|
def test_default_cache_key_fallback
|
||||||
render_object_with_cache(@comment)
|
render_object_with_cache(@comment)
|
||||||
key = "#{@comment.cache_key}/#{adapter.cached_name}"
|
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
||||||
assert_equal(@comment_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
assert_equal(@comment_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -139,9 +139,9 @@ module ActiveModelSerializers
|
|||||||
Timecop.freeze(Time.current) do
|
Timecop.freeze(Time.current) do
|
||||||
render_object_with_cache(@post)
|
render_object_with_cache(@post)
|
||||||
|
|
||||||
key = "#{@post.cache_key}/#{adapter.cached_name}"
|
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
||||||
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
||||||
key = "#{@comment.cache_key}/#{adapter.cached_name}"
|
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
||||||
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -152,9 +152,9 @@ module ActiveModelSerializers
|
|||||||
render_object_with_cache(@post)
|
render_object_with_cache(@post)
|
||||||
|
|
||||||
# Check if it cached the objects separately
|
# Check if it cached the objects separately
|
||||||
key = "#{@post.cache_key}/#{adapter.cached_name}"
|
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
||||||
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
||||||
key = "#{@comment.cache_key}/#{adapter.cached_name}"
|
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
||||||
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
||||||
|
|
||||||
# Simulating update on comments relationship with Post
|
# Simulating update on comments relationship with Post
|
||||||
@ -166,9 +166,9 @@ module ActiveModelSerializers
|
|||||||
render_object_with_cache(@post)
|
render_object_with_cache(@post)
|
||||||
|
|
||||||
# Check if the the new comment was cached
|
# Check if the the new comment was cached
|
||||||
key = "#{new_comment.cache_key}/#{adapter.cached_name}"
|
key = "#{new_comment.cache_key}/#{adapter.cache_key}"
|
||||||
assert_equal(new_comment_serializer.attributes, cache_store.fetch(key))
|
assert_equal(new_comment_serializer.attributes, cache_store.fetch(key))
|
||||||
key = "#{@post.cache_key}/#{adapter.cached_name}"
|
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
||||||
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -184,7 +184,7 @@ module ActiveModelSerializers
|
|||||||
hash = render_object_with_cache(@location)
|
hash = render_object_with_cache(@location)
|
||||||
|
|
||||||
assert_equal(hash, expected_result)
|
assert_equal(hash, expected_result)
|
||||||
key = "#{@location.cache_key}/#{adapter.cached_name}"
|
key = "#{@location.cache_key}/#{adapter.cache_key}"
|
||||||
assert_equal({ place: 'Nowhere' }, cache_store.fetch(key))
|
assert_equal({ place: 'Nowhere' }, cache_store.fetch(key))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ module ActiveModelSerializers
|
|||||||
|
|
||||||
def test_uses_file_digest_in_cache_key
|
def test_uses_file_digest_in_cache_key
|
||||||
render_object_with_cache(@blog)
|
render_object_with_cache(@blog)
|
||||||
key = "#{@blog.cache_key}/#{adapter.cached_name}/#{::Model::FILE_DIGEST}"
|
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{::Model::FILE_DIGEST}"
|
||||||
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
|
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -291,7 +291,7 @@ module ActiveModelSerializers
|
|||||||
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter, include_directive)
|
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter, include_directive)
|
||||||
|
|
||||||
assert_equal 3, actual.size
|
assert_equal 3, actual.size
|
||||||
assert actual.any? { |key| key == "comment/1/#{serializable.adapter.cached_name}" }
|
assert actual.any? { |key| key == "comment/1/#{serializable.adapter.cache_key}" }
|
||||||
assert actual.any? { |key| key =~ %r{post/post-\d+} }
|
assert actual.any? { |key| key =~ %r{post/post-\d+} }
|
||||||
assert actual.any? { |key| key =~ %r{author/author-\d+} }
|
assert actual.any? { |key| key =~ %r{author/author-\d+} }
|
||||||
end
|
end
|
||||||
@ -306,13 +306,13 @@ module ActiveModelSerializers
|
|||||||
include_directive = ActiveModelSerializers.default_include_directive
|
include_directive = ActiveModelSerializers.default_include_directive
|
||||||
cached_attributes = ActiveModel::Serializer.cache_read_multi(serializer, attributes, include_directive)
|
cached_attributes = ActiveModel::Serializer.cache_read_multi(serializer, attributes, include_directive)
|
||||||
|
|
||||||
assert_equal cached_attributes["#{@comment.cache_key}/#{attributes.cached_name}"], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
|
assert_equal cached_attributes["#{@comment.cache_key}/#{attributes.cache_key}"], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
|
||||||
assert_equal cached_attributes["#{@comment.post.cache_key}/#{attributes.cached_name}"], Post.new(id: 'post', title: 'New Post', body: 'Body').attributes
|
assert_equal cached_attributes["#{@comment.post.cache_key}/#{attributes.cache_key}"], Post.new(id: 'post', title: 'New Post', body: 'Body').attributes
|
||||||
|
|
||||||
writer = @comment.post.blog.writer
|
writer = @comment.post.blog.writer
|
||||||
writer_cache_key = writer.cache_key
|
writer_cache_key = writer.cache_key
|
||||||
|
|
||||||
assert_equal cached_attributes["#{writer_cache_key}/#{attributes.cached_name}"], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
|
assert_equal cached_attributes["#{writer_cache_key}/#{attributes.cache_key}"], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -22,15 +22,6 @@ ActionController::TestCase.class_eval do
|
|||||||
def setup
|
def setup
|
||||||
@routes = Routes
|
@routes = Routes
|
||||||
end
|
end
|
||||||
|
|
||||||
# For Rails5
|
|
||||||
# https://github.com/rails/rails/commit/ca83436d1b3b6cedd1eca2259f65661e69b01909#diff-b9bbf56e85d3fe1999f16317f2751e76L17
|
|
||||||
def assigns(key = nil)
|
|
||||||
warn "DEPRECATION: Calling 'assigns(#{key})' from #{caller[0]}"
|
|
||||||
assigns = {}.with_indifferent_access
|
|
||||||
@controller.view_assigns.each { |k, v| assigns.regular_writer(k, v) }
|
|
||||||
key.nil? ? assigns : assigns[key]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../test/dummy/db/migrate", __FILE__)]
|
# ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../test/dummy/db/migrate", __FILE__)]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user