Permalink
Browse files

Allow configuration of the default action cache path for #caches_acti…

…on calls. [Rick Olson]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6453 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent f39fe30 commit c6d72608418989952dbb9a9b09d42c0eed74b9f1 @technoweenie technoweenie committed Mar 22, 2007
Showing with 66 additions and 2 deletions.
  1. +9 −0 actionpack/CHANGELOG
  2. +26 −2 actionpack/lib/action_controller/caching.rb
  3. +31 −0 actionpack/test/controller/caching_test.rb
View
@@ -1,5 +1,14 @@
*SVN*
+* Allow configuration of the default action cache path for #caches_action calls. [Rick Olson]
+
+ class ListsController < ApplicationController
+ caches_action :index, :cache_path => Proc.new { |controller|
+ controller.params[:user_id] ?
+ controller.send(:user_lists_url, c.params[:user_id]) :
+ controller.send(:lists_url) }
+ end
+
* Performance: patch cgi/session/pstore to require digest/md5 once rather than per #initialize. #7583 [Stefan Kaes]
* Cookie session store: ensure that new sessions doesn't reuse data from a deleted session in the same request. [Jeremy Kemper]
@@ -161,6 +161,19 @@ def caching_allowed
# Different representations of the same resource, e.g. <tt>http://david.somewhere.com/lists</tt> and <tt>http://david.somewhere.com/lists.xml</tt>
# are treated like separate requests and so are cached separately. Keep in mind when expiring an action cache that <tt>:action => 'lists'</tt> is not the same
# as <tt>:action => 'list', :format => :xml</tt>.
+ #
+ # You can set modify the default action cache path by passing a :cache_path option. This will be passed directly to ActionCachePath.path_for. 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.
+ #
+ # class ListsController < ApplicationController
+ # before_filter :authenticate, :except => :public
+ # caches_page :public
+ # caches_action :show, :cache_path => { :project => 1 }
+ # caches_action :show, :cache_path => Proc.new { |controller|
+ # controller.params[:user_id] ?
+ # controller.send(:user_list_url, c.params[:user_id], c.params[:id]) :
+ # controller.send(:list_url, c.params[:id]) }
+ # end
module Actions
def self.included(base) #:nodoc:
base.extend(ClassMethods)
@@ -188,11 +201,12 @@ def expire_action(options = {})
class ActionCacheFilter #:nodoc:
def initialize(*actions, &block)
@actions = actions
+ @options = @actions.last.is_a?(Hash) ? @actions.pop : {}
end
def before(controller)
return unless @actions.include?(controller.action_name.intern)
- action_cache_path = ActionCachePath.new(controller)
+ action_cache_path = ActionCachePath.new(controller, path_options_for(controller))
if cache = controller.read_fragment(action_cache_path.path)
controller.rendered_action_cache = true
set_content_type!(action_cache_path)
@@ -203,7 +217,7 @@ def before(controller)
def after(controller)
return if !@actions.include?(controller.action_name.intern) || controller.rendered_action_cache
- controller.write_fragment(ActionCachePath.path_for(controller), controller.response.body)
+ controller.write_fragment(ActionCachePath.path_for(controller, path_options_for(controller)), controller.response.body)
end
private
@@ -215,6 +229,10 @@ def set_content_type!(action_cache_path)
end
end
+ def path_options_for(controller)
+ (@options[:cache_path].respond_to?(:call) ? @options[:cache_path].call(controller) : @options[:cache_path]) || {}
+ end
+
end
class ActionCachePath
@@ -598,6 +616,12 @@ def after(controller)
self.controller = nil
end
+ protected
+ # gets the action cache path for the given options.
+ def action_path_for(options)
+ ActionController::Caching::Actions::ActionCachePath.path_for(controller, options)
+ end
+
private
def callback(timing)
controller_callback_method_name = "#{timing}_#{controller.controller_name.underscore}"
@@ -98,11 +98,16 @@ def page_cached?(action)
class ActionCachingTestController < ActionController::Base
caches_action :index
+ 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" }
def index
@cache_this = Time.now.to_f.to_s
render :text => @cache_this
end
+
+ alias_method :show, :index
+ alias_method :edit, :index
def expire
expire_action :controller => 'action_caching_test', :action => 'index'
@@ -148,11 +153,32 @@ def test_simple_action_cache
get :index
cached_time = content_to_cache
assert_equal cached_time, @response.body
+ assert_cache_exists 'hostname.com/action_caching_test'
reset!
get :index
assert_equal cached_time, @response.body
end
+
+ def test_action_cache_with_custom_cache_path
+ get :show
+ cached_time = content_to_cache
+ assert_equal cached_time, @response.body
+ assert_cache_exists 'test.host/custom/show'
+ reset!
+
+ get :show
+ assert_equal cached_time, @response.body
+ end
+
+ def test_action_cache_with_custom_cache_path_in_block
+ get :edit
+ assert_cache_exists 'test.host/edit'
+ reset!
+
+ get :edit, :id => 1
+ assert_cache_exists 'test.host/1;edit'
+ end
def test_cache_expiration
get :index
@@ -228,4 +254,9 @@ def reset!
@controller = ActionCachingTestController.new
@request.host = 'hostname.com'
end
+
+ def assert_cache_exists(path)
+ full_path = File.join(FILE_STORE_PATH, path + '.cache')
+ assert File.exist?(full_path), "#{full_path.inspect} does not exist."
+ end
end

0 comments on commit c6d7260

Please sign in to comment.