From d2ad99be40234e08bdb05af4fbd8da6230e5a3e2 Mon Sep 17 00:00:00 2001 From: Nando Vieira Date: Sat, 18 Sep 2010 20:36:44 -0300 Subject: [PATCH] Make redirect_to accept blocks --- .../lib/action_controller/metal/redirecting.rb | 6 +++- actionpack/test/controller/redirect_test.rb | 38 ++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletions(-) diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index 10d7794..fb50fca 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -20,6 +20,7 @@ module ActionController # * Record - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record. # * String starting with protocol:// (like http://) - Is passed straight through as the target for redirection. # * String not containing a protocol - The current protocol and host is prepended to the string. + # * Proc - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+. # * :back - Back to the page that issued the request. Useful for forms that are triggered from multiple places. # Short-hand for redirect_to(request.env["HTTP_REFERER"]) # @@ -30,6 +31,7 @@ module ActionController # redirect_to "/images/screenshot.jpg" # redirect_to articles_url # redirect_to :back + # redirect_to proc { edit_post_url(@post) } # # The redirection happens as a "302 Moved" header unless otherwise specified. # @@ -38,7 +40,7 @@ module ActionController # redirect_to :action=>'atom', :status => :moved_permanently # redirect_to post_url(@post), :status => 301 # redirect_to :action=>'atom', :status => 302 - # + # # The status code can either be a standard {HTTP Status code}[http://www.iana.org/assignments/http-status-codes] as an # integer, or a symbol representing the downcased, underscored and symbolized description. # @@ -85,6 +87,8 @@ module ActionController when :back raise RedirectBackError unless refer = request.headers["Referer"] refer + when Proc + _compute_redirect_to_location instance_eval(&options) else url_for(options) end.gsub(/[\r\n]/, '') diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb index c30921a..b00142c 100644 --- a/actionpack/test/controller/redirect_test.rb +++ b/actionpack/test/controller/redirect_test.rb @@ -99,6 +99,19 @@ class RedirectController < ActionController::Base redirect_to nil end + def redirect_to_with_block + redirect_to proc { "http://www.rubyonrails.org/" } + end + + def redirect_to_with_block_and_assigns + @url = "http://www.rubyonrails.org/" + redirect_to proc { @url } + end + + def redirect_to_with_block_and_options + redirect_to proc { {:action => "hello_world"} } + end + def rescue_errors(e) raise e end def rescue_action(e) raise end @@ -252,6 +265,31 @@ class RedirectTest < ActionController::TestCase get :redirect_to_nil end end + + def test_redirect_to_with_block + get :redirect_to_with_block + assert_response :redirect + assert_redirected_to "http://www.rubyonrails.org/" + end + + def test_redirect_to_with_block_and_assigns + get :redirect_to_with_block_and_assigns + assert_response :redirect + assert_redirected_to "http://www.rubyonrails.org/" + end + + def test_redirect_to_with_block_and_accepted_options + with_routing do |set| + set.draw do + match ':controller/:action' + end + + get :redirect_to_with_block_and_options + + assert_response :redirect + assert_redirected_to "http://test.host/redirect/hello_world" + end + end end module ModuleTest -- 1.7.2.3