From 6b014a4580a8f17ebb73b441e029c0bb7d34a8c5 Mon Sep 17 00:00:00 2001 From: Fabrizio Regini Date: Thu, 29 Nov 2012 16:16:18 +0100 Subject: [PATCH] Allow fragment cache to accept :if and :unless options [Stephen Ausman + Fabrizio Regini] --- actionpack/CHANGELOG.md | 6 ++ .../lib/action_view/helpers/cache_helper.rb | 14 +++- .../test/controller/log_subscriber_test.rb | 64 +++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 91028e48c86bd..b57408ede371f 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,4 +1,10 @@ ## Rails 4.0.0 (unreleased) ## +* Add :if / :unless conditions to fragment cache: + + <%= cache @model, if: some_condition(@model) do %> + + *Stephen Ausman + Fabrizio Regini* + * Add filter capability to ActionController logs for redirect locations: config.filter_redirect << 'http://please.hide.it/' diff --git a/actionpack/lib/action_view/helpers/cache_helper.rb b/actionpack/lib/action_view/helpers/cache_helper.rb index db920ae7a42a4..8693f4f0e4f24 100644 --- a/actionpack/lib/action_view/helpers/cache_helper.rb +++ b/actionpack/lib/action_view/helpers/cache_helper.rb @@ -110,8 +110,15 @@ module CacheHelper # <%= some_helper_method(person) %> # # Now all you'll have to do is change that timestamp when the helper method changes. + # + # ==== Conditional caching + # + # You can pass :if and :unless options, to conditionally perform or skip the cache. + # + # <%= cache @model, if: some_condition(@model) do %> + # def cache(name = {}, options = nil, &block) - if controller.perform_caching + if controller.perform_caching && conditions_match?(options) safe_concat(fragment_for(cache_fragment_name(name, options), options, &block)) else yield @@ -136,6 +143,11 @@ def cache_fragment_name(name = {}, options = nil) end private + + def conditions_match?(options) + !(options && (!options.fetch(:if, true) || options.fetch(:unless, false))) + end + def fragment_name_with_digest(name) #:nodoc: if @virtual_path [ diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb index 7b4d49be20096..d8b971f9630d5 100644 --- a/actionpack/test/controller/log_subscriber_test.rb +++ b/actionpack/test/controller/log_subscriber_test.rb @@ -46,6 +46,22 @@ def with_fragment_cache_and_percent_in_key render :inline => "<%= cache('foo%bar'){ 'Contains % sign in key' } %>" end + def with_fragment_cache_and_if_true_condition + render :inline => "<%= cache('foo', :if => true) { 'bar' } %>" + end + + def with_fragment_cache_and_if_false_condition + render :inline => "<%= cache('foo', :if => false) { 'bar' } %>" + end + + def with_fragment_cache_and_unless_false_condition + render :inline => "<%= cache('foo', :unless => false) { 'bar' } %>" + end + + def with_fragment_cache_and_unless_true_condition + render :inline => "<%= cache('foo', :unless => true) { 'bar' } %>" + end + def with_exception raise Exception end @@ -203,6 +219,54 @@ def test_with_fragment_cache @controller.config.perform_caching = true end + def test_with_fragment_cache_and_if_true + @controller.config.perform_caching = true + get :with_fragment_cache_and_if_true_condition + wait + + assert_equal 4, logs.size + assert_match(/Read fragment views\/foo/, logs[1]) + assert_match(/Write fragment views\/foo/, logs[2]) + ensure + @controller.config.perform_caching = true + end + + def test_with_fragment_cache_and_if_false + @controller.config.perform_caching = true + get :with_fragment_cache_and_if_false_condition + wait + + assert_equal 2, logs.size + assert_no_match(/Read fragment views\/foo/, logs[1]) + assert_no_match(/Write fragment views\/foo/, logs[2]) + ensure + @controller.config.perform_caching = true + end + + def test_with_fragment_cache_and_unless_true + @controller.config.perform_caching = true + get :with_fragment_cache_and_unless_true_condition + wait + + assert_equal 2, logs.size + assert_no_match(/Read fragment views\/foo/, logs[1]) + assert_no_match(/Write fragment views\/foo/, logs[2]) + ensure + @controller.config.perform_caching = true + end + + def test_with_fragment_cache_and_unless_false + @controller.config.perform_caching = true + get :with_fragment_cache_and_unless_false_condition + wait + + assert_equal 4, logs.size + assert_match(/Read fragment views\/foo/, logs[1]) + assert_match(/Write fragment views\/foo/, logs[2]) + ensure + @controller.config.perform_caching = true + end + def test_with_fragment_cache_and_percent_in_key @controller.config.perform_caching = true get :with_fragment_cache_and_percent_in_key