diff --git a/lib/active_model/array_serializer.rb b/lib/active_model/array_serializer.rb index e92ad04a..a3b760cf 100644 --- a/lib/active_model/array_serializer.rb +++ b/lib/active_model/array_serializer.rb @@ -19,26 +19,18 @@ module ActiveModel class_attribute :root - def initialize(object, options={}) - @object, @options = object, options + class_attribute :cache + class_attribute :perform_caching + + class << self + # set peform caching like root + def cached(value = true) + self.perform_caching = value + end end - def serializable_array - @object.map do |item| - if @options.has_key? :each_serializer - serializer = @options[:each_serializer] - elsif item.respond_to?(:active_model_serializer) - serializer = item.active_model_serializer - end - - serializable = serializer ? serializer.new(item, @options) : DefaultSerializer.new(item) - - if serializable.respond_to?(:serializable_hash) - serializable.serializable_hash - else - serializable.as_json - end - end + def initialize(object, options={}) + @object, @options = object, options end def meta_key @@ -61,6 +53,52 @@ module ActiveModel serializable_array end end - end + def to_json(*args) + if perform_caching? + cache.fetch expand_cache_key([self.class.to_s.underscore, cache_key, 'to-json']) do + super + end + else + super + end + end + + def serializable_array + if perform_caching? + cache.fetch expand_cache_key([self.class.to_s.underscore, cache_key, 'serializable-array']) do + _serializable_array + end + else + _serializable_array + end + end + + private + def _serializable_array + @object.map do |item| + if @options.has_key? :each_serializer + serializer = @options[:each_serializer] + elsif item.respond_to?(:active_model_serializer) + serializer = item.active_model_serializer + end + + serializable = serializer ? serializer.new(item, @options) : DefaultSerializer.new(item) + + if serializable.respond_to?(:serializable_hash) + serializable.serializable_hash + else + serializable.as_json + end + end + end + + def expand_cache_key(*args) + ActiveSupport::Cache.expand_cache_key(args) + end + + def perform_caching? + perform_caching && cache && respond_to?(:cache_key) + end + end end diff --git a/lib/active_model_serializers.rb b/lib/active_model_serializers.rb index 992a4713..b904d7d7 100644 --- a/lib/active_model_serializers.rb +++ b/lib/active_model_serializers.rb @@ -26,7 +26,10 @@ if defined?(Rails) initializer "caching.active_model_serializer" do |app| ActiveModel::Serializer.perform_caching = app.config.action_controller.perform_caching + ActiveModel::ArraySerializer.perform_caching = app.config.action_controller.perform_caching + ActiveModel::Serializer.cache = Rails.cache + ActiveModel::ArraySerializer.cache = Rails.cache end end end diff --git a/test/caching_test.rb b/test/caching_test.rb index 53327985..e7ec5816 100644 --- a/test/caching_test.rb +++ b/test/caching_test.rb @@ -121,4 +121,26 @@ class CachingTest < ActiveModel::TestCase assert serializer.cache.read('serializer/custom-key/to-json') assert serializer.cache.read('serializer/custom-key/serializable-hash') end + + def test_array_serializer_uses_cache + serializer = Class.new(ActiveModel::ArraySerializer) do + cached true + + def self.to_s + 'array_serializer' + end + + def cache_key + 'cache-key' + end + end + + serializer.cache = NullStore.new + instance = serializer.new [Programmer.new] + + instance.to_json + + assert serializer.cache.read('array_serializer/cache-key/serializable-array') + assert serializer.cache.read('array_serializer/cache-key/to-json') + end end