Permalink
Browse files

Allow to use non-proc object in cache_path option

You can use :cache_path option with object that respond to #call method.
Before this patch ActionCacheFilter check that object respond to #call
method and execute #instance_exec on controller instance. It was strange
because #instance_exec method can work only with Proc objects.

When you pass Proc object to :cache_option it will be execute #instance_exec
with this Proc otherwise when object is respond to #call method will be called
on this object.

  class CachePath
    def call(controller)
      controller.id
    end
  end

  class TestController < ApplicationController
    caches_action :index, :cache_path => CachePath.new
    def index; end
  end
  • Loading branch information...
1 parent a594ca4 commit 11c4a0af04bce8fbb78eec04225a61cb5ac44ff0 @LTe LTe committed Feb 9, 2013
Showing with 35 additions and 1 deletion.
  1. +17 −1 lib/action_controller/caching/actions.rb
  2. +18 −0 test/caching_test.rb
@@ -43,6 +43,8 @@ module Caching
# <tt>ActionCachePath.new</tt>. This is handy for actions with
# multiple possible routes that should be cached differently. If a
# block is given, it is called with the current controller instance.
+ # If a object is given, it is called <tt>call</tt> method with the
+ # current controller instance.
#
# And you can also use <tt>:if</tt> (or <tt>:unless</tt>) to pass a
# proc that specifies when the action should be cached.
@@ -51,6 +53,16 @@ module Caching
# interval (in seconds) to schedule expiration of the cached item.
#
# The following example depicts some of the points made above:
+ # class CachePathCreator
+ # def initialize(name)
+ # @name = name
+ # end
+ #
+ # def call(controller)
+ # "cache-path-#{@name}"
+ # end
+ # end
+ #
#
# class ListsController < ApplicationController
# before_filter :authenticate, except: :public
@@ -71,6 +83,8 @@ module Caching
# list_url(params[:id])
# end
# end
+ #
+ # caches_action :posts, cache_path: CachePathCreator.new('posts')
# end
#
# If you pass <tt>layout: false</tt>, it will only cache your action
@@ -139,8 +153,10 @@ def initialize(options, &block)
def around(controller)
cache_layout = @cache_layout.respond_to?(:call) ? @cache_layout.call(controller) : @cache_layout
- path_options = if @cache_path.respond_to?(:call)
+ path_options = if @cache_path.is_a?(Proc)
controller.instance_exec(controller, &@cache_path)
+ elsif @cache_path.respond_to?(:call)
+ @cache_path.call(controller)
else
@cache_path
end
View
@@ -10,6 +10,12 @@ class CachingController < ActionController::Base
self.cache_store = :file_store, FILE_STORE_PATH
end
+class CachePath
+ def call(controller)
+ ['controller', controller.params[:id]].compact.join('-')
+ end
+end
+
class ActionCachingTestController < CachingController
rescue_from(Exception) { head 500 }
rescue_from(ActionController::UnknownFormat) { head :not_acceptable }
@@ -23,6 +29,7 @@ class ActionCachingTestController < CachingController
caches_action :index, :redirected, :forbidden, if: Proc.new { |c| c.request.format && !c.request.format.json? }, expires_in: 1.hour
caches_action :show, cache_path: 'http://test.host/custom/show'
caches_action :edit, cache_path: Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : 'http://test.host/edit' }
+ caches_action :custom_cache_path, cache_path: CachePath.new
caches_action :with_layout
caches_action :with_format_and_http_param, cache_path: Proc.new { |c| { key: 'value' } }
caches_action :layout_false, layout: false
@@ -73,6 +80,7 @@ def simple_runtime_error
alias_method :show, :index
alias_method :edit, :index
alias_method :destroy, :index
+ alias_method :custom_cache_path, :index
alias_method :layout_false, :with_layout
alias_method :with_layout_proc_param, :with_layout
@@ -291,6 +299,16 @@ def test_action_cache_with_custom_cache_path_in_block
assert fragment_exist?('test.host/1;edit')
end
+ def test_action_cache_with_custom_cache_path_with_custom_object
+ get :custom_cache_path
+ assert_response :success
+ assert fragment_exist?('controller')
+
+ get :custom_cache_path, id: 1
+ assert_response :success
+ assert fragment_exist?('controller-1')
+ end
+
def test_cache_expiration
get :index
assert_response :success

0 comments on commit 11c4a0a

Please sign in to comment.