mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
Refactor fragment cache methods
Removed extra calls to constantize and DRY'd the code.
This commit is contained in:
parent
f8d2aabf38
commit
efb09051ea
@ -21,7 +21,7 @@ Features:
|
|||||||
- [#1340](https://github.com/rails-api/active_model_serializers/pull/1340) Add support for resource-level meta. (@beauby)
|
- [#1340](https://github.com/rails-api/active_model_serializers/pull/1340) Add support for resource-level meta. (@beauby)
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
- [#1516](https://github.com/rails-api/active_model_serializers/pull/1501) No longer return a nil href when only
|
- [#1516](https://github.com/rails-api/active_model_serializers/pull/1516) No longer return a nil href when only
|
||||||
adding meta to a relationship link. (@groyoh)
|
adding meta to a relationship link. (@groyoh)
|
||||||
- [#1458](https://github.com/rails-api/active_model_serializers/pull/1458) Preserve the serializer
|
- [#1458](https://github.com/rails-api/active_model_serializers/pull/1458) Preserve the serializer
|
||||||
type when fragment caching. (@bdmac)
|
type when fragment caching. (@bdmac)
|
||||||
@ -31,6 +31,7 @@ Fixes:
|
|||||||
- [#1488](https://github.com/rails-api/active_model_serializers/pull/1488) Require ActiveSupport's string inflections (@nate00)
|
- [#1488](https://github.com/rails-api/active_model_serializers/pull/1488) Require ActiveSupport's string inflections (@nate00)
|
||||||
|
|
||||||
Misc:
|
Misc:
|
||||||
|
- [#1527](https://github.com/rails-api/active_model_serializers/pull/1527) Refactor fragment cache class. (@groyoh)
|
||||||
- [#1560](https://github.com/rails-api/active_model_serializers/pull/1560) Update rubocop and address its warnings. (@bf4 @groyoh)
|
- [#1560](https://github.com/rails-api/active_model_serializers/pull/1560) Update rubocop and address its warnings. (@bf4 @groyoh)
|
||||||
- [#1545](https://github.com/rails-api/active_model_serializers/pull/1545) Document how to pass arbitrary options to the
|
- [#1545](https://github.com/rails-api/active_model_serializers/pull/1545) Document how to pass arbitrary options to the
|
||||||
serializer (@CodedBeardedSignedTaylor)
|
serializer (@CodedBeardedSignedTaylor)
|
||||||
|
|||||||
@ -9,26 +9,18 @@ module ActiveModelSerializers
|
|||||||
@serializer = serializer
|
@serializer = serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: Use Serializable::Resource
|
|
||||||
# TODO: call +constantize+ less
|
|
||||||
# 1. Create a CachedSerializer and NonCachedSerializer from the serializer class
|
# 1. Create a CachedSerializer and NonCachedSerializer from the serializer class
|
||||||
# 2. Serialize the above two with the given adapter
|
# 2. Serialize the above two with the given adapter
|
||||||
# 3. Pass their serializations to the adapter +::fragment_cache+
|
# 3. Pass their serializations to the adapter +::fragment_cache+
|
||||||
def fetch
|
def fetch
|
||||||
klass = serializer.class
|
object = serializer.object
|
||||||
|
|
||||||
# It will split the serializer into two, one that will be cached and one that will not
|
# It will split the serializer into two, one that will be cached and one that will not
|
||||||
serializers = fragment_serializer(serializer.object.class.name, klass)
|
serializers = fragment_serializer(object.class.name)
|
||||||
|
|
||||||
# Instantiate both serializers
|
|
||||||
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, instance_options)
|
|
||||||
non_cached_adapter = adapter.class.new(non_cached_serializer, instance_options)
|
|
||||||
|
|
||||||
# Get serializable hash from both
|
# Get serializable hash from both
|
||||||
cached_hash = cached_adapter.serializable_hash
|
cached_hash = serialize(object, serializers[:cached])
|
||||||
non_cached_hash = non_cached_adapter.serializable_hash
|
non_cached_hash = serialize(object, serializers[:non_cached])
|
||||||
|
|
||||||
# Merge both results
|
# Merge both results
|
||||||
adapter.fragment_cache(cached_hash, non_cached_hash)
|
adapter.fragment_cache(cached_hash, non_cached_hash)
|
||||||
@ -40,31 +32,38 @@ module ActiveModelSerializers
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Given a serializer class and a hash of its cached and non-cached serializers
|
def serialize(object, serializer_class)
|
||||||
|
ActiveModel::SerializableResource.new(
|
||||||
|
object,
|
||||||
|
serializer: serializer_class,
|
||||||
|
adapter: adapter.class
|
||||||
|
).serializable_hash
|
||||||
|
end
|
||||||
|
|
||||||
|
# Given a hash of its cached and non-cached serializers
|
||||||
# 1. Determine cached attributes from serializer class options
|
# 1. Determine cached attributes from serializer class options
|
||||||
# 2. Add cached attributes to cached Serializer
|
# 2. Add cached attributes to cached Serializer
|
||||||
# 3. Add non-cached attributes to non-cached Serializer
|
# 3. Add non-cached attributes to non-cached Serializer
|
||||||
def cached_attributes(klass, serializers)
|
def cache_attributes(serializers)
|
||||||
attributes = serializer.class._attributes
|
klass = serializer.class
|
||||||
cached_attributes = klass._cache_only ? klass._cache_only : attributes.reject { |attr| klass._cache_except.include?(attr) }
|
attributes = klass._attributes
|
||||||
|
cache_only = klass._cache_only
|
||||||
|
cached_attributes = cache_only ? cache_only : attributes - klass._cache_except
|
||||||
non_cached_attributes = attributes - cached_attributes
|
non_cached_attributes = attributes - cached_attributes
|
||||||
|
attributes_keys = klass._attributes_keys
|
||||||
|
|
||||||
cached_attributes.each do |attribute|
|
add_attributes_to_serializer(serializers[:cached], cached_attributes, attributes_keys)
|
||||||
options = serializer.class._attributes_keys[attribute]
|
add_attributes_to_serializer(serializers[:non_cached], non_cached_attributes, attributes_keys)
|
||||||
options ||= {}
|
end
|
||||||
# Add cached attributes to cached Serializer
|
|
||||||
serializers[:cached].constantize.attribute(attribute, options)
|
|
||||||
end
|
|
||||||
|
|
||||||
non_cached_attributes.each do |attribute|
|
def add_attributes_to_serializer(serializer, attributes, attributes_keys)
|
||||||
options = serializer.class._attributes_keys[attribute]
|
attributes.each do |attribute|
|
||||||
options ||= {}
|
options = attributes_keys[attribute] || {}
|
||||||
# Add non-cached attributes to non-cached Serializer
|
serializer.attribute(attribute, options)
|
||||||
serializers[:non_cached].constantize.attribute(attribute, options)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Given a resource name and its serializer's class
|
# Given a resource name
|
||||||
# 1. Dyanmically creates a CachedSerializer and NonCachedSerializer
|
# 1. Dyanmically creates a CachedSerializer and NonCachedSerializer
|
||||||
# for a given class 'name'
|
# for a given class 'name'
|
||||||
# 2. Call
|
# 2. Call
|
||||||
@ -81,30 +80,36 @@ module ActiveModelSerializers
|
|||||||
# User_AdminCachedSerializer
|
# User_AdminCachedSerializer
|
||||||
# User_AdminNOnCachedSerializer
|
# User_AdminNOnCachedSerializer
|
||||||
#
|
#
|
||||||
def fragment_serializer(name, klass)
|
def fragment_serializer(name)
|
||||||
|
klass = serializer.class
|
||||||
cached = "#{to_valid_const_name(name)}CachedSerializer"
|
cached = "#{to_valid_const_name(name)}CachedSerializer"
|
||||||
non_cached = "#{to_valid_const_name(name)}NonCachedSerializer"
|
non_cached = "#{to_valid_const_name(name)}NonCachedSerializer"
|
||||||
|
|
||||||
Object.const_set cached, Class.new(ActiveModel::Serializer) unless Object.const_defined?(cached)
|
cached_serializer = get_or_create_serializer(cached)
|
||||||
Object.const_set non_cached, Class.new(ActiveModel::Serializer) unless Object.const_defined?(non_cached)
|
non_cached_serializer = get_or_create_serializer(non_cached)
|
||||||
|
|
||||||
klass._cache_options ||= {}
|
klass._cache_options ||= {}
|
||||||
klass._cache_options[:key] = klass._cache_key if klass._cache_key
|
cache_key = klass._cache_key
|
||||||
|
klass._cache_options[:key] = cache_key if cache_key
|
||||||
|
cached_serializer.cache(klass._cache_options)
|
||||||
|
|
||||||
cached.constantize.cache(klass._cache_options)
|
type = klass._type
|
||||||
|
cached_serializer.type(type)
|
||||||
|
non_cached_serializer.type(type)
|
||||||
|
|
||||||
# Preserve the type setting in the cached/non-cached serializer classes
|
non_cached_serializer.fragmented(serializer)
|
||||||
cached.constantize.type(klass._type)
|
cached_serializer.fragmented(serializer)
|
||||||
non_cached.constantize.type(klass._type)
|
|
||||||
|
|
||||||
cached.constantize.fragmented(serializer)
|
serializers = { cached: cached_serializer, non_cached: non_cached_serializer }
|
||||||
non_cached.constantize.fragmented(serializer)
|
cache_attributes(serializers)
|
||||||
|
|
||||||
serializers = { cached: cached, non_cached: non_cached }
|
|
||||||
cached_attributes(klass, serializers)
|
|
||||||
serializers
|
serializers
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_or_create_serializer(name)
|
||||||
|
return Object.const_get(name) if Object.const_defined?(name)
|
||||||
|
Object.const_set(name, Class.new(ActiveModel::Serializer))
|
||||||
|
end
|
||||||
|
|
||||||
def to_valid_const_name(name)
|
def to_valid_const_name(name)
|
||||||
name.gsub('::', '_')
|
name.gsub('::', '_')
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user