Fix fragment caching inherited serializers to use distinct per-serializer caches.

This commit is contained in:
Logan Serman 2016-03-25 16:24:43 -05:00
parent 5af7d96294
commit d0389ca765
3 changed files with 24 additions and 7 deletions

View File

@ -26,6 +26,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:
- [#1622](https://github.com/rails-api/active_model_serializers/pull/1622) Fix fragment caching inherited serializers to use distinct per-serializer caches. (@lserman)
- [#1478](https://github.com/rails-api/active_model_serializers/pull/1478) Cache store will now be correctly set when serializers are - [#1478](https://github.com/rails-api/active_model_serializers/pull/1478) Cache store will now be correctly set when serializers are
loaded *before* Rails initializes. (@bf4) loaded *before* Rails initializes. (@bf4)
- [#1570](https://github.com/rails-api/active_model_serializers/pull/1570) Fixed pagination issue with last page size. (@bmorrall) - [#1570](https://github.com/rails-api/active_model_serializers/pull/1570) Fixed pagination issue with last page size. (@bmorrall)

View File

@ -15,7 +15,7 @@ module ActiveModelSerializers
object = serializer.object 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(object.class.name) serializers = fragment_serializer
# Get serializable hash from both # Get serializable hash from both
cached_hash = serialize(object, serializers[:cached]) cached_hash = serialize(object, serializers[:cached])
@ -79,10 +79,12 @@ module ActiveModelSerializers
# User_AdminCachedSerializer # User_AdminCachedSerializer
# User_AdminNonCachedSerializer # User_AdminNonCachedSerializer
# #
def fragment_serializer(name) def fragment_serializer
klass = serializer.class klass = serializer.class
cached = "#{to_valid_const_name(name)}CachedSerializer" serializer_class_name = to_valid_const_name(klass.name)
non_cached = "#{to_valid_const_name(name)}NonCachedSerializer"
cached = "Cached#{serializer_class_name}"
non_cached = "NonCached#{serializer_class_name}"
cached_serializer = get_or_create_serializer(cached) cached_serializer = get_or_create_serializer(cached)
non_cached_serializer = get_or_create_serializer(non_cached) non_cached_serializer = get_or_create_serializer(non_cached)

View File

@ -1,6 +1,12 @@
require 'test_helper' require 'test_helper'
require 'tmpdir' require 'tmpdir'
require 'tempfile' require 'tempfile'
InheritedRoleSerializer = Class.new(RoleSerializer) do
cache key: 'inherited_role', only: [:name, :special_attribute]
attribute :special_attribute
end
module ActiveModelSerializers module ActiveModelSerializers
class CacheTest < ActiveSupport::TestCase class CacheTest < ActiveSupport::TestCase
def setup def setup
@ -150,6 +156,14 @@ module ActiveModelSerializers
assert_equal({ place: 'Nowhere' }, ActionController::Base.cache_store.fetch(@location.cache_key)) assert_equal({ place: 'Nowhere' }, ActionController::Base.cache_store.fetch(@location.cache_key))
end end
def test_fragment_cache_with_inheritance
inherited = render_object_with_cache(@role, serializer: InheritedRoleSerializer)
base = render_object_with_cache(@role)
assert_includes(inherited.keys, :special_attribute)
refute_includes(base.keys, :special_attribute)
end
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)
assert_equal(@blog_serializer.attributes, ActionController::Base.cache_store.fetch(@blog.cache_key_with_digest)) assert_equal(@blog_serializer.attributes, ActionController::Base.cache_store.fetch(@blog.cache_key_with_digest))
@ -242,8 +256,8 @@ module ActiveModelSerializers
private private
def render_object_with_cache(obj) def render_object_with_cache(obj, options = {})
ActiveModel::SerializableResource.new(obj).serializable_hash ActiveModel::SerializableResource.new(obj, options).serializable_hash
end end
end end
end end