4.5 Redirecting
The life cycle of a Rails application is divided into requests. Rendering a template, whether the default one or an alternate one—or, for that matter, rendering a partial or some text or anything—is the final step in the handling of a request. Redirecting, however, means terminating the current request and asking the client to initiate a new one.
Look again at the example of the form-handling create method:
def create
if @event.save
flash[:notice] = "Event created!"
redirect_to :index
else
render :new
end
end
If the save operation succeeds, we store a message in the flash hash and redirect_to a completely new action. In this case, it’s the index action. The logic here is that if the new Event record gets saved, the next order of business is to take the user back to the top-level view.
The main reason to redirect rather than just render a template after creating or editing a resource (really a POST action) has to do with browser reload behavior. If you didn’t redirect, the user would be prompted to rem-subit the form if they hit the back button or reload.
4.5.1 The redirect_to Method
The redirect_to method takes two parameters:
redirect_to (target, response_status={})
The target
parameter takes one of the several forms.
Hash - The URL will be generated by calling url_for
with the argument provided.
redirect_to action:"show", id:5
Active Record object - The URL will be generated by calling url_for
with the object provided, which should generate a named URL for that record.
redirect_to post
String starting with protocol like http:// - Used directly as the target url for redirection.
redirect_to "http://www.rubyonrails.org"
redirect_to articles_url
String not containing a protocol - The current protocol and host is prepended to the argument and used for
redirection.
redirect_to "/"
redirect_to articles_path
: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"])
. When using redirect_to :back
, if there is no referrer set, a RedirectBackError
will be raised. You may specify some fallback behavior for this case by rescuing RedirectBackError
.
Redirection happens as a “302 Moved” header unless otherwise specified. The response_status
parameter takes a hash of arguments. The code can be specified by name or number, as in the following examples:
redirect_to post_url(@post), status: :found
redirect_to :atom, status: :moved_permanently
redirect_to post_url(@post), status:301
redirect_to :atom, status:302
It is also possible to assign a flash
message as part of the redirection. There are two special accessors for commonly used the flash names alert
and notice
as well as a general purpose flash bucket.
redirect_to post_url(@post), alert:"Watchit,mister!"
redirect_to post_url(@post), status: :found, notice: "Pay attention to the road"
redirect_to post_url(@post), status:301, flash: {:updated_post_id => @post.id}
redirect_to :atom, alert: "Something serious happened"
New to Rails 4, is the ability to register your own flash types by using the new ActionController::Flash.add_flash_types
macro style method.
classApplicationController
...
add_flash_types :error
end
When a flash type is registered, a special flash accessor similar to alert and notice, becomes available to be used with redirect_to.
redirect_to post_url(@post), error: "Something went really wrong!"
Remember that redirect and render statements don’t magically halt execution of your con- troller action method. To prevent
DoubleRenderError
, consider explicitly calling return after redirect_to or render like this:
def show
@user = User.find(params[:id])
if @user.activated?
render :activated and return
end
...
end