From 6a175a527fe05fdf8bfa134f0f756fecb64475c0 Mon Sep 17 00:00:00 2001 From: lcp Date: Fri, 11 Dec 2015 17:38:01 +0800 Subject: [PATCH] support read_multi --- .../serializer/adapter/attributes.rb | 17 +++++++++++ .../serializer/adapter/cached_serializer.rb | 28 +++++++++++++++++++ test/serializers/cache_test.rb | 12 ++++++++ 3 files changed, 57 insertions(+) diff --git a/lib/active_model/serializer/adapter/attributes.rb b/lib/active_model/serializer/adapter/attributes.rb index 49dea8607..52fec33fd 100644 --- a/lib/active_model/serializer/adapter/attributes.rb +++ b/lib/active_model/serializer/adapter/attributes.rb @@ -24,6 +24,15 @@ def fragment_cache(cached_hash, non_cached_hash) private def serializable_hash_for_collection(options) + if options[:batch_cache].blank? && ActiveModelSerializers.config.cache_store.present? + keys = CachedSerializer.object_cache_keys(serializer, @include_tree) + if keys.present? + values = ActiveModelSerializers.config.cache_store.read_multi(*keys) + + options.merge!(batch_cache: values) + end + end + serializer.map { |s| Attributes.new(s, instance_options).serializable_hash(options) } end @@ -56,6 +65,14 @@ def include_meta(json) end def resource_object_for(options) + if options[:batch_cache].present? + cache_key = CachedSerializer.new(serializer).cache_key + + value = options[:batch_cache][cache_key] + + return value if value.present? + end + cache_check(serializer) do serializer.attributes(options[:fields]) end diff --git a/lib/active_model/serializer/adapter/cached_serializer.rb b/lib/active_model/serializer/adapter/cached_serializer.rb index 35b101689..3b976471a 100644 --- a/lib/active_model/serializer/adapter/cached_serializer.rb +++ b/lib/active_model/serializer/adapter/cached_serializer.rb @@ -39,6 +39,34 @@ def object_cache_key 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 + + # collection_serializer with the include_tree + def self.object_cache_keys(serializers, include_tree) + cache_keys = [] + + serializers.each do |serializer| + cache_keys << object_cache_key(serializer) + + serializer.associations(include_tree).each do |association| + if association.serializer.respond_to?(:each) + association.serializer.each do |sub_serializer| + cache_keys << object_cache_key(sub_serializer) + end + else + cache_keys << object_cache_key(association.serializer) + end + end + end + + cache_keys.compact + end + + def self.object_cache_key(serializer) + return unless serializer.present? && serializer.object.present? + + cached_serializer = new(serializer) + cached_serializer.cached? ? cached_serializer.cache_key : nil + end end end end diff --git a/test/serializers/cache_test.rb b/test/serializers/cache_test.rb index d6b33edca..0cd9a6741 100644 --- a/test/serializers/cache_test.rb +++ b/test/serializers/cache_test.rb @@ -149,6 +149,18 @@ def test_cache_digest_definition assert_equal(::Model::FILE_DIGEST, @post_serializer.class._cache_digest) end + def test_object_cache_keys + serializer = CollectionSerializer.new([@comment, @comment]) + include_tree = IncludeTree.from_include_args('*') + + actual = Serializer::Adapter::CachedSerializer.object_cache_keys(serializer, include_tree) + + assert_equal actual.size, 6 + assert actual.any? { |key| key == 'comment/1' } + assert actual.any? { |key| key =~ %r{post/post-\d+} } + assert actual.any? { |key| key =~ %r{writer/author-\d+} } + end + def test_serializer_file_path_on_nix path = '/Users/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb' caller_line = "#{path}:1:in `'"