Index: test/fragment_cache_test.rb =================================================================== --- test/fragment_cache_test.rb (revision 270) +++ test/fragment_cache_test.rb (working copy) @@ -21,6 +21,10 @@ render :text => "doop!" end + def trees_are_swell? + true + end + def rescue_action(e) raise e end @@ -160,4 +164,26 @@ get :index end + + specify "should be able to action cache conditionally when passed something that returns true" do + BarController.caches_action :page => { :if => :trees_are_swell? } + + cache_expects(:set).with('test.host/bar/page', page_content, ActsAsCached.config[:ttl]) + + get :page + @response.body.should == page_content + + cache_expects(:read).with('test.host/bar/page', nil).returns(page_content) + + get :page + end + + specify "should be able to skip action caching when passed something that returns false" do + BarController.caches_action :page => { :if => Proc.new {|c| !c.trees_are_swell?} } + + cache_expects(:set, 0).with('test.host/bar/page', page_content, ActsAsCached.config[:ttl]) + + get :page + @response.body.should == page_content + end end Index: lib/acts_as_cached/fragment_cache.rb =================================================================== --- lib/acts_as_cached/fragment_cache.rb (revision 270) +++ lib/acts_as_cached/fragment_cache.rb (working copy) @@ -36,6 +36,31 @@ end end end + + # override to skip caching/rendering on evaluated if option + def before(controller) + return unless @actions.include?(controller.action_name.intern) + action_cache_path = ActionController::Caching::Actions::ActionCachePath.new(controller) + conditional = @actions[controller.action_name.intern][:if] + + # should probably be like ActiveRecord::Validations.evaluate_condition. color me lazy. + if conditional + conditional = if conditional.respond_to?("call") + conditional.call(controller) + elsif controller.send(conditional) + true + end + end + @actions.delete(controller.action_name.intern) if conditional == false + + cache = controller.read_fragment(action_cache_path.path) + if (cache and (conditional || conditional.nil?)) + controller.rendered_action_cache = true + set_content_type!(action_cache_path) + controller.send(:render_text, cache) + return false + end + end # override to pass along the ttl hash def after(controller)