aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xactionpack/lib/action_controller/base.rb12
-rw-r--r--actionpack/lib/action_controller/rescue.rb1
-rw-r--r--activerecord/CHANGELOG4
3 files changed, 15 insertions, 2 deletions
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 160318c98b..5eba5c7167 100755
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -24,6 +24,8 @@ module ActionController #:nodoc:
end
class MissingFile < ActionControllerError #:nodoc:
end
+ class DoubleRenderError < ActionControllerError #:nodoc:
+ end
# Action Controllers are made up of one or more actions that performs its purpose and then either renders a template or
# redirects to another action. An action is defined as a public method on the controller, which will automatically be
@@ -476,7 +478,7 @@ 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?
+ raise DoubleRenderError, "Can only render or redirect once per action" if performed?
add_variables_to_assigns
@response.headers["Status"] = status.to_s || DEFAULT_RENDER_STATUS_CODE
@response.body = block_given? ? block : text
@@ -494,6 +496,12 @@ module ActionController #:nodoc:
add_variables_to_assigns
@template.render_file(template_name)
end
+
+ # Clears the rendered results, allowing for another render or redirect to be performed.
+ def erase_render_results #:nodoc:
+ @response.body = nil
+ @performed_render = false
+ end
# Renders the partial specified by <tt>partial_path</tt>, which by default is the name of the action itself. Example:
#
@@ -659,7 +667,7 @@ 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?
+ raise DoubleRenderError, "Can only render or redirect once per action" if performed?
logger.info("Redirected to #{url}") unless logger.nil?
@response.redirect(url, permanently)
@performed_redirect = true
diff --git a/actionpack/lib/action_controller/rescue.rb b/actionpack/lib/action_controller/rescue.rb
index 2ee320a304..376a7f1aec 100644
--- a/actionpack/lib/action_controller/rescue.rb
+++ b/actionpack/lib/action_controller/rescue.rb
@@ -25,6 +25,7 @@ module ActionController #:nodoc:
# Exception handler called when the performance of an action raises an exception.
def rescue_action(exception)
log_error(exception) unless logger.nil?
+ erase_render_results if performed?
if consider_all_requests_local || local_request?
rescue_action_locally(exception)
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 5769b84d14..82c8e5b6df 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,9 @@
*SVN*
+* Added DoubleRenderError exception that'll be raised if render* is called twice #518 [Nicholas Seckar]
+
+* Fixed exceptions occuring after render has been called #1096 [Nicholas Seckar]
+
* CHANGED: validates_presence_of now uses Errors#add_on_blank, which will make " " fail the validation where it didn't before #1309
* Added Errors#add_on_blank which works like Errors#add_on_empty, but uses Object#blank? instead