aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/CHANGELOG2
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb20
-rw-r--r--actionpack/test/controller/caching_test.rb15
3 files changed, 34 insertions, 3 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 9622029362..ba2b16849c 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,3 +1,5 @@
+* Allow caches_action to accept a layout option [José Valim]
+
* Added Rack processor [Ezra Zygmuntowicz, Josh Peek]
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index 1ef9e60a21..c4b0a97a33 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -40,6 +40,8 @@ module ActionController #:nodoc:
# controller.send(:list_url, c.params[:id]) }
# end
#
+ # If you pass :layout => false, it will only cache your action content. It is useful when your layout has dynamic information.
+ #
module Actions
def self.included(base) #:nodoc:
base.extend(ClassMethods)
@@ -54,7 +56,8 @@ module ActionController #:nodoc:
def caches_action(*actions)
return unless cache_configured?
options = actions.extract_options!
- around_filter(ActionCacheFilter.new(:cache_path => options.delete(:cache_path)), {:only => actions}.merge(options))
+ cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path))
+ around_filter(cache_filter, {:only => actions}.merge(options))
end
end
@@ -81,7 +84,9 @@ module ActionController #:nodoc:
if cache = controller.read_fragment(cache_path.path)
controller.rendered_action_cache = true
set_content_type!(controller, cache_path.extension)
- controller.send!(:render_for_text, cache)
+ options = { :text => cache }
+ options.merge!(:layout => true) if cache_layout?
+ controller.send!(:render, options)
false
else
controller.action_cache_path = cache_path
@@ -90,7 +95,8 @@ module ActionController #:nodoc:
def after(controller)
return if controller.rendered_action_cache || !caching_allowed(controller)
- controller.write_fragment(controller.action_cache_path.path, controller.response.body)
+ action_content = cache_layout? ? content_for_layout(controller) : controller.response.body
+ controller.write_fragment(controller.action_cache_path.path, action_content)
end
private
@@ -105,6 +111,14 @@ module ActionController #:nodoc:
def caching_allowed(controller)
controller.request.get? && controller.response.headers['Status'].to_i == 200
end
+
+ def cache_layout?
+ @options[:layout] == false
+ end
+
+ def content_for_layout(controller)
+ controller.response.layout && controller.response.template.instance_variable_get('@content_for_layout')
+ end
end
class ActionCachePath
diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb
index f9b6b87bc6..c6d61bb504 100644
--- a/actionpack/test/controller/caching_test.rb
+++ b/actionpack/test/controller/caching_test.rb
@@ -156,6 +156,7 @@ class ActionCachingTestController < ActionController::Base
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 :with_layout
+ caches_action :layout_false, :layout => false
layout 'talk_from_action.erb'
@@ -181,6 +182,7 @@ class ActionCachingTestController < ActionController::Base
alias_method :show, :index
alias_method :edit, :index
alias_method :destroy, :index
+ alias_method :layout_false, :with_layout
def expire
expire_action :controller => 'action_caching_test', :action => 'index'
@@ -263,6 +265,19 @@ class ActionCacheTest < Test::Unit::TestCase
assert_equal @response.body, read_fragment('hostname.com/action_caching_test/with_layout')
end
+ def test_action_cache_with_layout_and_layout_cache_false
+ get :layout_false
+ cached_time = content_to_cache
+ assert_not_equal cached_time, @response.body
+ assert fragment_exist?('hostname.com/action_caching_test/layout_false')
+ reset!
+
+ get :layout_false
+ assert_not_equal cached_time, @response.body
+
+ assert_equal cached_time, read_fragment('hostname.com/action_caching_test/layout_false')
+ end
+
def test_action_cache_conditional_options
@request.env['HTTP_ACCEPT'] = 'application/json'
get :index