diff --git a/CHANGELOG.md b/CHANGELOG.md index 8666ca74..25e98887 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Breaking changes: Features: Fixes: + - [#2288](https://github.com/rails-api/active_model_serializers/pull/2288). Fixes #2287. (@cintamani) - [#2307](https://github.com/rails-api/active_model_serializers/pull/2307) Falsey attribute values should not be reevaluated. diff --git a/Gemfile b/Gemfile index 79f6b954..59f77c9d 100644 --- a/Gemfile +++ b/Gemfile @@ -53,7 +53,7 @@ group :bench do end group :test do - gem 'sqlite3', platform: (@windows_platforms + [:ruby]) + gem 'sqlite3', '~> 1.3.13', platform: (@windows_platforms + [:ruby]) platforms :jruby do if version == 'master' || version >= '5' gem 'activerecord-jdbcsqlite3-adapter', '~> 50' diff --git a/lib/active_model/serializer/concerns/caching.rb b/lib/active_model/serializer/concerns/caching.rb index ff72ca01..35bd8e64 100644 --- a/lib/active_model/serializer/concerns/caching.rb +++ b/lib/active_model/serializer/concerns/caching.rb @@ -283,7 +283,9 @@ module ActiveModel # Use object's cache_key if available, else derive a key from the object # Pass the `key` option to the `cache` declaration or override this method to customize the cache key def object_cache_key - if object.respond_to?(:cache_key) + if object.respond_to?(:cache_key_with_version) + object.cache_key_with_version + elsif object.respond_to?(:cache_key) object.cache_key elsif (serializer_cache_key = (serializer_class._cache_key || serializer_class._cache_options[:key])) object_time_safe = object.updated_at diff --git a/test/cache_test.rb b/test/cache_test.rb index 7bf9ca85..9f82317a 100644 --- a/test/cache_test.rb +++ b/test/cache_test.rb @@ -55,6 +55,11 @@ module ActiveModelSerializers has_many :roles has_one :bio end + class AuthorSerializerWithCache < ActiveModel::Serializer + cache + + attributes :name + end class Blog < ::Model attributes :name @@ -146,6 +151,65 @@ module ActiveModelSerializers @blog_serializer = BlogSerializer.new(@blog) end + def test_expiring_of_cache_at_update_of_record + original_cache_versioning = :none + + if ARModels::Author.respond_to?(:cache_versioning) + original_cache_versioning = ARModels::Author.cache_versioning + ARModels::Author.cache_versioning = true + end + + author = ARModels::Author.create(name: 'Foo') + author_json = AuthorSerializerWithCache.new(author).as_json + + assert_equal 'Foo', author_json[:name] + + author.update_attributes(name: 'Bar') + author_json = AuthorSerializerWithCache.new(author).as_json + + expected = 'Bar' + actual = author_json[:name] + if ENV['APPVEYOR'] && actual != expected + skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)') + else + assert_equal expected, actual + end + ensure + ARModels::Author.cache_versioning = original_cache_versioning unless original_cache_versioning == :none + end + + def test_cache_expiration_in_collection_on_update_of_record + original_cache_versioning = :none + + if ARModels::Author.respond_to?(:cache_versioning) + original_cache_versioning = ARModels::Author.cache_versioning + ARModels::Author.cache_versioning = true + end + + foo = 'Foo' + foo2 = 'Foo2' + author = ARModels::Author.create(name: foo) + author2 = ARModels::Author.create(name: foo2) + author_collection = [author, author, author2] + + collection_json = render_object_with_cache(author_collection, each_serializer: AuthorSerializerWithCache) + actual = collection_json + expected = [{ name: foo }, { name: foo }, { name: foo2 }] + if ENV['APPVEYOR'] && actual != expected + skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)') + else + assert_equal expected, actual + end + + bar = 'Bar' + author.update!(name: bar) + + collection_json = render_object_with_cache(author_collection, each_serializer: AuthorSerializerWithCache) + assert_equal [{ name: bar }, { name: bar }, { name: foo2 }], collection_json + ensure + ARModels::Author.cache_versioning = original_cache_versioning unless original_cache_versioning == :none + end + def test_explicit_cache_store default_store = Class.new(ActiveModel::Serializer) do cache