Distinguish options ivar from local; Extract latent Adapter::CachedSerializer

This commit is contained in:
Benjamin Fleischer
2015-09-16 22:12:13 -05:00
parent 3f0794bd39
commit 9d65f0adc5
10 changed files with 131 additions and 100 deletions

View File

@@ -0,0 +1,45 @@
module ActiveModel
class Serializer
class Adapter
class CachedSerializer
def initialize(serializer)
@cached_serializer = serializer
@klass = @cached_serializer.class
end
def cache_check(adapter_instance)
if cached?
@klass._cache.fetch(cache_key, @klass._cache_options) do
yield
end
elsif fragment_cached?
FragmentCache.new(adapter_instance, @cached_serializer, adapter_instance.instance_options).fetch
else
yield
end
end
def cached?
@klass._cache && !@klass._cache_only && !@klass._cache_except
end
def fragment_cached?
@klass._cache_only && !@klass._cache_except || !@klass._cache_only && @klass._cache_except
end
def cache_key
parts = []
parts << object_cache_key
parts << @klass._cache_digest unless @klass._cache_options && @klass._cache_options[:skip_digest]
parts.join('/')
end
def object_cache_key
object_time_safe = @cached_serializer.object.updated_at
object_time_safe = object_time_safe.strftime('%Y%m%d%H%M%S%9N') if object_time_safe.respond_to?(:strftime)
(@klass._cache_key) ? "#{@klass._cache_key}/#{@cached_serializer.object.id}-#{object_time_safe}" : @cached_serializer.object.cache_key
end
end
end
end
end

View File

@@ -2,7 +2,7 @@ class ActiveModel::Serializer::Adapter::FragmentCache
attr_reader :serializer
def initialize(adapter, serializer, options)
@options = options
@instance_options = options
@adapter = adapter
@serializer = serializer
end
@@ -16,19 +16,23 @@ class ActiveModel::Serializer::Adapter::FragmentCache
cached_serializer = serializers[:cached].constantize.new(serializer.object)
non_cached_serializer = serializers[:non_cached].constantize.new(serializer.object)
cached_adapter = @adapter.class.new(cached_serializer, @options)
non_cached_adapter = @adapter.class.new(non_cached_serializer, @options)
cached_adapter = adapter.class.new(cached_serializer, instance_options)
non_cached_adapter = adapter.class.new(non_cached_serializer, instance_options)
# Get serializable hash from both
cached_hash = cached_adapter.serializable_hash
non_cached_hash = non_cached_adapter.serializable_hash
# Merge both results
@adapter.fragment_cache(cached_hash, non_cached_hash)
adapter.fragment_cache(cached_hash, non_cached_hash)
end
private
ActiveModelSerializers.silence_warnings do
attr_reader :instance_options, :adapter
end
def cached_attributes(klass, serializers)
attributes = serializer.class._attributes
cached_attributes = (klass._cache_only) ? klass._cache_only : attributes.reject { |attr| klass._cache_except.include?(attr) }

View File

@@ -15,13 +15,13 @@ class ActiveModel::Serializer::Adapter::Json < ActiveModel::Serializer::Adapter
serializer.associations.each do |association|
serializer = association.serializer
opts = association.options
association_options = association.options
if serializer.respond_to?(:each)
array_serializer = serializer
hash[association.key] = array_serializer.map do |item|
cache_check(item) do
item.attributes(opts)
item.attributes(association_options)
end
end
else
@@ -30,8 +30,8 @@ class ActiveModel::Serializer::Adapter::Json < ActiveModel::Serializer::Adapter
cache_check(serializer) do
serializer.attributes(options)
end
elsif opts[:virtual_value]
opts[:virtual_value]
elsif association_options[:virtual_value]
association_options[:virtual_value]
end
end
end

View File

@@ -5,7 +5,7 @@ class ActiveModel::Serializer::Adapter::JsonApi < ActiveModel::Serializer::Adapt
def initialize(serializer, options = {})
super
@included = ActiveModel::Serializer::Utils.include_args_to_hash(@options[:include])
@included = ActiveModel::Serializer::Utils.include_args_to_hash(instance_options[:include])
fields = options.delete(:fields)
if fields
@fieldset = ActiveModel::Serializer::Fieldset.new(fields, serializer.json_key)
@@ -24,16 +24,20 @@ class ActiveModel::Serializer::Adapter::JsonApi < ActiveModel::Serializer::Adapt
end
def fragment_cache(cached_hash, non_cached_hash)
root = false if @options.include?(:include)
root = false if instance_options.include?(:include)
ActiveModel::Serializer::Adapter::JsonApi::FragmentCache.new.fragment_cache(root, cached_hash, non_cached_hash)
end
private
ActiveModel.silence_warnings do
attr_reader :included, :fieldset
end
def serializable_hash_for_collection(serializer, options)
hash = { data: [] }
serializer.each do |s|
result = self.class.new(s, @options.merge(fieldset: @fieldset)).serializable_hash(options)
result = self.class.new(s, instance_options.merge(fieldset: fieldset)).serializable_hash(options)
hash[:data] << result[:data]
if result[:included]
@@ -85,7 +89,7 @@ class ActiveModel::Serializer::Adapter::JsonApi < ActiveModel::Serializer::Adapt
end
def resource_object_for(serializer, options = {})
options[:fields] = @fieldset && @fieldset.fields_for(serializer)
options[:fields] = fieldset && fieldset.fields_for(serializer)
cache_check(serializer) do
result = resource_identifier_for(serializer)
@@ -120,12 +124,10 @@ class ActiveModel::Serializer::Adapter::JsonApi < ActiveModel::Serializer::Adapt
end
def included_for(serializer)
included = @included.flat_map do |inc|
included.flat_map { |inc|
association = serializer.associations.find { |assoc| assoc.key == inc.first }
_included_for(association.serializer, inc.second) if association
end
included.uniq
}.uniq
end
def _included_for(serializer, includes)
@@ -134,7 +136,7 @@ class ActiveModel::Serializer::Adapter::JsonApi < ActiveModel::Serializer::Adapt
else
return [] unless serializer && serializer.object
primary_data = primary_data_for(serializer, @options)
primary_data = primary_data_for(serializer, instance_options)
relationships = relationships_for(serializer)
primary_data[:relationships] = relationships if relationships.any?