Skip to content

Commit 15b7974

Browse files
authored
Merge pull request #2288 from cintamani/patch-1
Change the fetch method to deal with recyclable key cache strategy
2 parents 209834d + be7f083 commit 15b7974

File tree

4 files changed

+69
-2
lines changed

4 files changed

+69
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Breaking changes:
77
Features:
88

99
Fixes:
10+
- [#2288](https://github.com/rails-api/active_model_serializers/pull/2288). Fixes #2287. (@cintamani)
1011

1112
- [#2307](https://github.com/rails-api/active_model_serializers/pull/2307) Falsey attribute values should not be reevaluated.
1213

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ group :bench do
5353
end
5454

5555
group :test do
56-
gem 'sqlite3', platform: (@windows_platforms + [:ruby])
56+
gem 'sqlite3', '~> 1.3.13', platform: (@windows_platforms + [:ruby])
5757
platforms :jruby do
5858
if version == 'master' || version >= '5'
5959
gem 'activerecord-jdbcsqlite3-adapter', '~> 50'

lib/active_model/serializer/concerns/caching.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,9 @@ def expand_cache_key(parts)
283283
# Use object's cache_key if available, else derive a key from the object
284284
# Pass the `key` option to the `cache` declaration or override this method to customize the cache key
285285
def object_cache_key
286-
if object.respond_to?(:cache_key)
286+
if object.respond_to?(:cache_key_with_version)
287+
object.cache_key_with_version
288+
elsif object.respond_to?(:cache_key)
287289
object.cache_key
288290
elsif (serializer_cache_key = (serializer_class._cache_key || serializer_class._cache_options[:key]))
289291
object_time_safe = object.updated_at

test/cache_test.rb

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ class AuthorSerializer < ActiveModel::Serializer
5555
has_many :roles
5656
has_one :bio
5757
end
58+
class AuthorSerializerWithCache < ActiveModel::Serializer
59+
cache
60+
61+
attributes :name
62+
end
5863

5964
class Blog < ::Model
6065
attributes :name
@@ -146,6 +151,65 @@ class InheritedRoleSerializer < RoleSerializer
146151
@blog_serializer = BlogSerializer.new(@blog)
147152
end
148153

154+
def test_expiring_of_cache_at_update_of_record
155+
original_cache_versioning = :none
156+
157+
if ARModels::Author.respond_to?(:cache_versioning)
158+
original_cache_versioning = ARModels::Author.cache_versioning
159+
ARModels::Author.cache_versioning = true
160+
end
161+
162+
author = ARModels::Author.create(name: 'Foo')
163+
author_json = AuthorSerializerWithCache.new(author).as_json
164+
165+
assert_equal 'Foo', author_json[:name]
166+
167+
author.update_attributes(name: 'Bar')
168+
author_json = AuthorSerializerWithCache.new(author).as_json
169+
170+
expected = 'Bar'
171+
actual = author_json[:name]
172+
if ENV['APPVEYOR'] && actual != expected
173+
skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)')
174+
else
175+
assert_equal expected, actual
176+
end
177+
ensure
178+
ARModels::Author.cache_versioning = original_cache_versioning unless original_cache_versioning == :none
179+
end
180+
181+
def test_cache_expiration_in_collection_on_update_of_record
182+
original_cache_versioning = :none
183+
184+
if ARModels::Author.respond_to?(:cache_versioning)
185+
original_cache_versioning = ARModels::Author.cache_versioning
186+
ARModels::Author.cache_versioning = true
187+
end
188+
189+
foo = 'Foo'
190+
foo2 = 'Foo2'
191+
author = ARModels::Author.create(name: foo)
192+
author2 = ARModels::Author.create(name: foo2)
193+
author_collection = [author, author, author2]
194+
195+
collection_json = render_object_with_cache(author_collection, each_serializer: AuthorSerializerWithCache)
196+
actual = collection_json
197+
expected = [{ name: foo }, { name: foo }, { name: foo2 }]
198+
if ENV['APPVEYOR'] && actual != expected
199+
skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)')
200+
else
201+
assert_equal expected, actual
202+
end
203+
204+
bar = 'Bar'
205+
author.update!(name: bar)
206+
207+
collection_json = render_object_with_cache(author_collection, each_serializer: AuthorSerializerWithCache)
208+
assert_equal [{ name: bar }, { name: bar }, { name: foo2 }], collection_json
209+
ensure
210+
ARModels::Author.cache_versioning = original_cache_versioning unless original_cache_versioning == :none
211+
end
212+
149213
def test_explicit_cache_store
150214
default_store = Class.new(ActiveModel::Serializer) do
151215
cache

0 commit comments

Comments
 (0)