Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the fetch method to deal with recyclable key cache strategy #2288

Merged
merged 16 commits into from
Feb 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
4 changes: 3 additions & 1 deletion lib/active_model/serializer/concerns/caching.rb
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,9 @@ def expand_cache_key(parts)
# 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
Expand Down
64 changes: 64 additions & 0 deletions test/cache_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ class AuthorSerializer < ActiveModel::Serializer
has_many :roles
has_one :bio
end
class AuthorSerializerWithCache < ActiveModel::Serializer
cache

attributes :name
end

class Blog < ::Model
attributes :name
Expand Down Expand Up @@ -146,6 +151,65 @@ class InheritedRoleSerializer < RoleSerializer
@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
cintamani marked this conversation as resolved.
Show resolved Hide resolved
end
cintamani marked this conversation as resolved.
Show resolved Hide resolved

author = ARModels::Author.create(name: 'Foo')
author_json = AuthorSerializerWithCache.new(author).as_json

assert_equal 'Foo', author_json[:name]

author.update_attributes(name: 'Bar')
cintamani marked this conversation as resolved.
Show resolved Hide resolved
cintamani marked this conversation as resolved.
Show resolved Hide resolved
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
cintamani marked this conversation as resolved.
Show resolved Hide resolved
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
Expand Down