support read_multi

This commit is contained in:
lcp 2015-12-11 17:38:01 +08:00
parent 7d4f0c5c8a
commit 43312fa083
3 changed files with 103 additions and 3 deletions

View File

@ -5,6 +5,7 @@ module ActiveModel
def initialize(serializer, options = {})
super
@include_tree = IncludeTree.from_include_args(options[:include] || '*')
@cached_attributes = options[:cache_attributes] || {}
end
def serializable_hash(options = nil)
@ -24,9 +25,38 @@ module ActiveModel
private
def serializable_hash_for_collection(options)
cache_attributes
serializer.map { |s| Attributes.new(s, instance_options).serializable_hash(options) }
end
# Read cache from cache_store
# @return [Hash]
def cache_read_multi
return {} if ActiveModelSerializers.config.cache_store.blank?
keys = CachedSerializer.object_cache_keys(serializer, @include_tree)
return {} if keys.blank?
ActiveModelSerializers.config.cache_store.read_multi(*keys)
end
# Set @cached_attributes
def cache_attributes
return if @cached_attributes.present?
@cached_attributes = cache_read_multi
end
# Get attributes from @cached_attributes
# @return [Hash] cached attributes
def cached_attributes(cached_serializer)
return yield unless cached_serializer.cached?
@cached_attributes.fetch(cached_serializer.cache_key) { yield }
end
def serializable_hash_for_single_resource(options)
resource = resource_object_for(options)
relationships = resource_relationships(options)
@ -56,8 +86,12 @@ module ActiveModel
end
def resource_object_for(options)
cache_check(serializer) do
serializer.attributes(options[:fields])
cached_serializer = CachedSerializer.new(serializer)
cached_attributes(cached_serializer) do
cached_serializer.cache_check(self) do
serializer.attributes(options[:fields])
end
end
end
end

View File

@ -28,10 +28,12 @@ module ActiveModel
end
def cache_key
return @cache_key if defined?(@cache_key)
parts = []
parts << object_cache_key
parts << @klass._cache_digest unless @klass._cache_options && @klass._cache_options[:skip_digest]
parts.join('/')
@cache_key = parts.join('/')
end
def object_cache_key
@ -39,6 +41,38 @@ module ActiveModel
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
# find all cache_key for the collection_serializer
# @param collection_serializer
# @param include_tree
# @return [Array] all cache_key of collection_serializer
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.uniq
end
# @return [String, nil] the cache_key of the serializer or nil
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

View File

@ -149,6 +149,38 @@ module ActiveModel
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, 3
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_cached_attributes
serializer = CollectionSerializer.new([@comment, @comment])
Timecop.freeze(Time.now) do
render_object_with_cache(@comment)
attributes = ActiveModel::Serializer::Adapter::Attributes.new(serializer)
attributes.send(:cache_attributes)
cached_attributes = attributes.instance_variable_get(:@cached_attributes)
assert_equal cached_attributes[@comment.cache_key], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
assert_equal cached_attributes[@comment.post.cache_key], Post.new(id: 'post', title: 'New Post', body: 'Body').attributes
writer = @comment.post.blog.writer
writer_cache_key = "writer/#{writer.id}-#{writer.updated_at.strftime("%Y%m%d%H%M%S%9N")}"
assert_equal cached_attributes[writer_cache_key], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
end
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 `<top (required)>'"