mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Enforce fresh ETag header after collection changes
Add ActiveRecord::Relation#cache_key_with_version. This method will be used by ActionController::ConditionalGet to ensure that when collection cache versioning is enabled, requests using ConditionalGet don't return the same ETag header after a collection is modified. Prior to the introduction of collection cache versioning in4f2ac80d4c
, all collection cache keys included a version. However, with cache versioning enabled, collection cache keys remain constant. In turn, ETag headers remain constant, rendering them ineffective. This commit takes the cache_key_with_version method used for individual Active Record objects (fromaa8749eb52
), and adds it to collections.
This commit is contained in:
parent
b8dc13050c
commit
58b040964f
3 changed files with 27 additions and 0 deletions
|
@ -1,3 +1,11 @@
|
|||
* Enforce fresh ETag header after a collection's contents change by adding
|
||||
ActiveRecord::Relation#cache_key_with_version. This method will be used by
|
||||
ActionController::ConditionalGet to ensure that when collection cache versioning
|
||||
is enabled, requests using ConditionalGet don't return the same ETag header
|
||||
after a collection is modified. Fixes #38078.
|
||||
|
||||
*Aaron Lipman*
|
||||
|
||||
* Skip test database when running `db:create` or `db:drop` in development
|
||||
with `DATABASE_URL` set.
|
||||
|
||||
|
|
|
@ -385,6 +385,15 @@ module ActiveRecord
|
|||
end
|
||||
private :compute_cache_version
|
||||
|
||||
# Returns a cache key along with the version.
|
||||
def cache_key_with_version
|
||||
if version = cache_version
|
||||
"#{cache_key}-#{version}"
|
||||
else
|
||||
cache_key
|
||||
end
|
||||
end
|
||||
|
||||
# Scope all queries to the current scope.
|
||||
#
|
||||
# Comment.where(post_id: 1).scoping do
|
||||
|
|
|
@ -198,6 +198,16 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
test "cache_key_with_version contains key and version regardless of collection_cache_versioning setting" do
|
||||
key_with_version_1 = Developer.all.cache_key_with_version
|
||||
assert_match(/\Adevelopers\/query-(\h+)-(\d+)-(\d+)\z/, key_with_version_1)
|
||||
|
||||
with_collection_cache_versioning do
|
||||
key_with_version_2 = Developer.all.cache_key_with_version
|
||||
assert_equal(key_with_version_1, key_with_version_2)
|
||||
end
|
||||
end
|
||||
|
||||
def with_collection_cache_versioning(value = true)
|
||||
@old_collection_cache_versioning = ActiveRecord::Base.collection_cache_versioning
|
||||
ActiveRecord::Base.collection_cache_versioning = value
|
||||
|
|
Loading…
Reference in a new issue