A ActionController::DoubleRenderError occurred in
(some action):
Render and/or redirect were called multiple times
in this action. Please note that you may only call
render OR redirect, and at most once per action.
Also note that neither redirect nor render
terminate execution of the action, so if you want
to exit an action after redirecting, you need to
do something like "redirect_to(...) and return".
When you get a DoubleRenderError, there is a good chance that something is happening as part of an action that you didn't anticipate, because you expected all action to stop when you did a render or redirect_to. So, bad things may be happening, like ignoring authentication, executing the action anyway, and then displaying to the user that either that he was unauthorized or displaying a page that is the result of a DoubleRenderError.
One cause of this is particularly insidious. :before_filter keeps track of whether a render or redirect_to was called and, if so, will stop the action. If you move a method previously called by the :before_filter to the action method itself, you may forget to return from the action if that method calls render or redirect_to. If you are lucky there will be another render or redirect_to and this will result in a DoubleRenderError, so you'll catch it and perhaps be alerted that something went wrong. However, an action getting executed unintentionally is not a good thing.
To avoid this, be sure that when you call a method that might render or redirect for that method to return a boolean that you can use in the calling method to return from the action.
The following authenticate method is fine when called by a :before_filter:
class MyController < ApplicationController
:before_filter authenticate
def authenticate
render :file => "public/401.html", :status => :unauthorized unless authorized?
end
def some_action
# do something important and possibly render or redirect_to
end
end
However, after moving this to the action method, you need to do a return:
class MyController < ApplicationController
def authenticate
auth = authorized?
render :file => "public/401.html", :status => :unauthorized unless auth
return auth
end
def some_action
return unless authenticate
# do something important and possibly render or redirect_to
end
def some_other_action
# this action is not authenticated or is authenticated differently,
# but still makes sense to include in this controller
end
end
0 comments:
Post a Comment