mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fixed that all redirect and render calls now return true, so you can use the pattern of "do and return". Added that renders and redirects called in before_filters will have the same effect as returning false: stopping the chain. Added that only one render or redirect can happen per action. The first call wins and subsequent calls are ignored.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@462 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
91ff8352a4
commit
2ee84cc6f9
4 changed files with 74 additions and 7 deletions
|
@ -1,3 +1,35 @@
|
|||
*SVN*
|
||||
|
||||
* Fixed that a default fragment store wan't being set to MemoryStore as intended.
|
||||
|
||||
* Fixed that all redirect and render calls now return true, so you can use the pattern of "do and return". Example:
|
||||
|
||||
def show
|
||||
redirect_to(:action => "login") and return unless @person.authenticated?
|
||||
render_text "I won't happen unless the person is authenticated"
|
||||
end
|
||||
|
||||
* Added that renders and redirects called in before_filters will have the same effect as returning false: stopping the chain. Example:
|
||||
|
||||
class WeblogController
|
||||
before_filter { |c| c.send(:redirect_to_url("http://www.farfaraway.com")}) }
|
||||
|
||||
def hello
|
||||
render_text "I will never be called"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
* Added that only one render or redirect can happen per action. The first call wins and subsequent calls are ignored. Example:
|
||||
|
||||
def do_something
|
||||
redirect_to :action => "elsewhere"
|
||||
render_action "overthere"
|
||||
end
|
||||
|
||||
Only the redirect happens. The rendering call is simply ignored.
|
||||
|
||||
|
||||
*1.3.1* (January 18th, 2005)
|
||||
|
||||
* Fixed a bug where cookies wouldn't be set if a symbol was used instead of a string as the key
|
||||
|
|
|
@ -163,6 +163,17 @@ module ActionController #:nodoc:
|
|||
# For more examples of redirecting options, have a look at the unit test in test/controller/url_test.rb. It's very readable and will give
|
||||
# you an excellent understanding of the different options and what they do.
|
||||
#
|
||||
# == Calling multiple redirects or renders
|
||||
#
|
||||
# The rule for handling calls of multiple redirects and renders is that the first call wins. So in the following example:
|
||||
#
|
||||
# def do_something
|
||||
# redirect_to :action => "elsewhere"
|
||||
# render_action "overthere"
|
||||
# end
|
||||
#
|
||||
# Only the redirect happens. The rendering call is simply ignored.
|
||||
#
|
||||
# == Environments
|
||||
#
|
||||
# Action Controller works out of the box with CGI, FastCGI, and mod_ruby. CGI and mod_ruby controllers are triggered just the same using:
|
||||
|
@ -385,11 +396,11 @@ module ActionController #:nodoc:
|
|||
# considerably faster than rendering through the template engine.
|
||||
# Use block for response body if provided (useful for deferred rendering or streaming output).
|
||||
def render_text(text = nil, status = nil, &block) #:doc:
|
||||
return if performed?
|
||||
add_variables_to_assigns
|
||||
@response.headers["Status"] = status || DEFAULT_RENDER_STATUS_CODE
|
||||
@response.body = block_given? ? block : text
|
||||
@performed_render = true
|
||||
return false
|
||||
end
|
||||
|
||||
# Renders an empty response that can be used when the request is only interested in triggering an effect. Do note that good
|
||||
|
@ -541,10 +552,10 @@ module ActionController #:nodoc:
|
|||
# <tt>redirect_to_url "http://www.rubyonrails.org"</tt>. If the resource has moved permanently, it's possible to pass true as the
|
||||
# second parameter and the browser will get "301 Moved Permanently" instead of "302 Found".
|
||||
def redirect_to_url(url, permanently = false) #:doc:
|
||||
return if performed?
|
||||
logger.info("Redirected to #{url}") unless logger.nil?
|
||||
@response.redirect(url, permanently)
|
||||
@performed_redirect = true
|
||||
return false
|
||||
end
|
||||
|
||||
# Resets the session by clearsing out all the objects stored within and initializing a new session object.
|
||||
|
@ -594,13 +605,17 @@ module ActionController #:nodoc:
|
|||
def perform_action
|
||||
if action_methods.include?(action_name) || action_methods.include?('method_missing')
|
||||
send(action_name)
|
||||
render unless @performed_render || @performed_redirect
|
||||
render unless performed?
|
||||
elsif template_exists? && template_public?
|
||||
render
|
||||
else
|
||||
raise UnknownAction, "No action responded to #{action_name}", caller
|
||||
end
|
||||
end
|
||||
|
||||
def performed?
|
||||
@performed_render || @performed_redirect
|
||||
end
|
||||
|
||||
def action_methods
|
||||
action_controller_classes = self.class.ancestors.reject{ |a| [Object, Kernel].include?(a) }
|
||||
|
|
|
@ -12,9 +12,9 @@ module ActionController #:nodoc:
|
|||
#
|
||||
# Filters have access to the request, response, and all the instance variables set by other filters in the chain
|
||||
# or by the action (in the case of after filters). Additionally, it's possible for a pre-processing <tt>before_filter</tt>
|
||||
# to halt the processing before the intended action is processed by returning false. This is especially useful for
|
||||
# filters like authentication where you're not interested in allowing the action to be performed if the proper
|
||||
# credentials are not in order.
|
||||
# to halt the processing before the intended action is processed by returning false or performing a redirect or render.
|
||||
# This is especially useful for filters like authentication where you're not interested in allowing the action to be
|
||||
# performed if the proper credentials are not in order.
|
||||
#
|
||||
# == Filter inheritance
|
||||
#
|
||||
|
@ -290,7 +290,7 @@ module ActionController #:nodoc:
|
|||
end
|
||||
|
||||
def perform_action_with_filters
|
||||
return if before_action == false
|
||||
return if before_action == false || performed?
|
||||
perform_action_without_filters
|
||||
after_action
|
||||
end
|
||||
|
|
|
@ -14,6 +14,20 @@ class FilterTest < Test::Unit::TestCase
|
|||
@ran_filter << "ensure_login"
|
||||
end
|
||||
end
|
||||
|
||||
class RenderingController < ActionController::Base
|
||||
before_filter :render_something_else
|
||||
|
||||
def show
|
||||
@ran_action = true
|
||||
render_text "ran action"
|
||||
end
|
||||
|
||||
private
|
||||
def render_something_else
|
||||
render_text "something else"
|
||||
end
|
||||
end
|
||||
|
||||
class ConditionalFilterController < ActionController::Base
|
||||
def show
|
||||
|
@ -264,6 +278,12 @@ class FilterTest < Test::Unit::TestCase
|
|||
" after appended aroundfilter after aroundfilter after procfilter ",
|
||||
MixedFilterController.execution_log
|
||||
end
|
||||
|
||||
def test_rendering_breaks_filtering_chain
|
||||
response = test_process(RenderingController)
|
||||
assert_equal "something else", response.body
|
||||
assert !response.template.assigns["ran_action"]
|
||||
end
|
||||
|
||||
private
|
||||
def test_process(controller, action = "show")
|
||||
|
|
Loading…
Reference in a new issue