From 1a404abc03d5c3a731ba826d63fde149bc7c1d30 Mon Sep 17 00:00:00 2001 From: Sam Stephenson Date: Mon, 14 Dec 2015 17:57:39 -0600 Subject: Remove ActionView::Helpers::CacheHelper#fragment_cache_key Introduced in e56c63542780fe2fb804636a875f95cae08ab3f4, `CacheHelper#fragment_cache_key` is a duplicate of `ActionController::Caching::Fragments#fragment_cache_key`. We now require the view to provide this method on its own (as with `view_cache_dependencies`); `ActionController::Caching::Fragments` exports its version as a `helper_method`. --- actionpack/lib/action_controller/caching/fragments.rb | 6 ++++++ actionview/lib/action_view/helpers/cache_helper.rb | 8 -------- actionview/test/template/render_test.rb | 4 ++++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb index 2694d4c12f..4e141659ee 100644 --- a/actionpack/lib/action_controller/caching/fragments.rb +++ b/actionpack/lib/action_controller/caching/fragments.rb @@ -14,6 +14,12 @@ module ActionController # # expire_fragment('name_of_cache') module Fragments + extend ActiveSupport::Concern + + included do + helper_method :fragment_cache_key if respond_to?(:helper_method) + end + # Given a key (as described in +expire_fragment+), returns # a key suitable for use in reading, writing, or expiring a # cached fragment. All keys are prefixed with views/ and uses diff --git a/actionview/lib/action_view/helpers/cache_helper.rb b/actionview/lib/action_view/helpers/cache_helper.rb index e473aeaea9..18b2102d73 100644 --- a/actionview/lib/action_view/helpers/cache_helper.rb +++ b/actionview/lib/action_view/helpers/cache_helper.rb @@ -216,14 +216,6 @@ module ActionView end end - # Given a key (as described in ActionController::Caching::Fragments.expire_fragment), - # returns a key suitable for use in reading, writing, or expiring a - # cached fragment. All keys are prefixed with views/ and uses - # ActiveSupport::Cache.expand_cache_key for the expansion. - def fragment_cache_key(key) - ActiveSupport::Cache.expand_cache_key(key.is_a?(Hash) ? url_for(key).split("://").last : key, :views) - end - private def fragment_name_with_digest(name, virtual_path) #:nodoc: diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb index 84aca222b2..994fd44c52 100644 --- a/actionview/test/template/render_test.rb +++ b/actionview/test/template/render_test.rb @@ -9,6 +9,10 @@ module RenderTestCases @assigns = { :secret => 'in the sauce' } @view = Class.new(ActionView::Base) do def view_cache_dependencies; end + + def fragment_cache_key(key) + ActiveSupport::Cache.expand_cache_key(key, :views) + end end.new(paths, @assigns) @controller_view = TestController.new.view_context -- cgit v1.2.3 From 99caf9ae7e46d15a713d821fa8cd516a4d254446 Mon Sep 17 00:00:00 2001 From: Sam Stephenson Date: Mon, 14 Dec 2015 19:53:43 -0600 Subject: Add fragment_cache_key macro for controller-wide fragment cache key prefixes --- .../lib/action_controller/caching/fragments.rb | 45 ++++++++++++++++++++-- actionpack/test/controller/caching_test.rb | 25 ++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb index 4e141659ee..c42384b741 100644 --- a/actionpack/lib/action_controller/caching/fragments.rb +++ b/actionpack/lib/action_controller/caching/fragments.rb @@ -17,15 +17,54 @@ module ActionController extend ActiveSupport::Concern included do + if respond_to?(:class_attribute) + class_attribute :fragment_cache_keys + else + mattr_writer :fragment_cache_keys + end + + self.fragment_cache_keys = [] + helper_method :fragment_cache_key if respond_to?(:helper_method) end + module ClassMethods + # Allows you to specify controller-wide key prefixes for + # cache fragments. Pass either a constant +value+, or a block + # which computes a value each time a cache key is generated. + # + # For example, you may want to prefix all fragment cache keys + # with a global version identifier, so you can easily + # invalidate all caches. + # + # class ApplicationController + # fragment_cache_key "v1" + # end + # + # When it's time to invalidate all fragments, simply change + # the string constant. Or, progressively roll out the cache + # invalidation using a computed value: + # + # class ApplicationController + # fragment_cache_key do + # @account.id.odd? ? "v1" : "v2" + # end + # end + def fragment_cache_key(value = nil, &key) + self.fragment_cache_keys += [key || ->{ value }] + end + end + # Given a key (as described in +expire_fragment+), returns # a key suitable for use in reading, writing, or expiring a - # cached fragment. All keys are prefixed with views/ and uses - # ActiveSupport::Cache.expand_cache_key for the expansion. + # cached fragment. All keys begin with views/, + # followed by any controller-wide key prefix values, ending + # with the specified +key+ value. The key is expanded using + # ActiveSupport::Cache.expand_cache_key. def fragment_cache_key(key) - ActiveSupport::Cache.expand_cache_key(key.is_a?(Hash) ? url_for(key).split("://").last : key, :views) + head = self.class.fragment_cache_keys.map { |key| instance_exec(&key) } + tail = key.is_a?(Hash) ? url_for(key).split("://").last : key + ActiveSupport::Cache.expand_cache_key([*head, *tail], :views) end # Writes +content+ to the location signified by diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index bc0ffd3eaa..d19b3810c2 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -419,3 +419,28 @@ class AutomaticCollectionCacheTest < ActionController::TestCase assert_equal 1, @controller.partial_rendered_times end end + +class FragmentCacheKeyTestController < CachingController + attr_accessor :account_id + + fragment_cache_key "v1" + fragment_cache_key { account_id } +end + +class FragmentCacheKeyTest < ActionController::TestCase + def setup + super + @store = ActiveSupport::Cache::MemoryStore.new + @controller = FragmentCacheKeyTestController.new + @controller.perform_caching = true + @controller.cache_store = @store + end + + def test_fragment_cache_key + @controller.account_id = "123" + assert_equal 'views/v1/123/what a key', @controller.fragment_cache_key('what a key') + + @controller.account_id = nil + assert_equal 'views/v1//what a key', @controller.fragment_cache_key('what a key') + end +end -- cgit v1.2.3