Correctly doing redirect_to :back in Ruby on Rails when referrer is not available
Ruby on-RailsRubyHttpRuby on-Rails Problem Overview
I'm having a problem with redirect_to :back
. Yes, it's referrers.
I often get the exception > (ActionController::RedirectBackError) "No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"]."
I realize that this is a result of a referrer not being available. Is there a way that, for example, one can set a session variable on each access with the last page visited, and, when HTTP_REFERER is not available, utilize this session variable to redirect to?
Ruby on-Rails Solutions
Solution 1 - Ruby on-Rails
It is unlikely that you do have a session and don't have a referrer.
The situation that a referrer is not set isn't that uncommon and I usually rescue that expection:
def some_method
redirect_to :back
rescue ActionController::RedirectBackError
redirect_to root_path
end
If you do this often (which I think is a bad idea) you can wrap it in an other method like Maran suggests.
BTW I think that's a bad idea because this makes the userflow ambiguous. Only in the case of a login this is sensible.
UPDATE: As several people pointed out this no longer works with Rails 5.
Instead, use redirect_back
, this method also supports a fallback. The code then becomes:
def some_method
redirect_back fallback_location: root_path
end
Solution 2 - Ruby on-Rails
Here's my little redirect_to_back method:
def redirect_to_back(default = root_url)
if request.env["HTTP_REFERER"].present? and request.env["HTTP_REFERER"] != request.env["REQUEST_URI"]
redirect_to :back
else
redirect_to default
end
end
You can pass an optional url to go somewhere else if http_refferrer is blank.
Solution 3 - Ruby on-Rails
def store_location
session[:return_to] = request.request_uri
end
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
Try that! (Thanks to the Authlogic plugin)
Solution 4 - Ruby on-Rails
Core feature
redirect_back
is a core feature from Rails 5+, it is available in the ActionController::Redirecting
module that is already included inApplicationController::Base
.
> DEPRECATION WARNING: redirect_to :back
is deprecated and will be removed from Rails 5.1. Please use redirect_back(fallback_location: fallback_location)
where fallback_location
represents the location to use if the request has no HTTP referer information.
EDIT : source
Solution 5 - Ruby on-Rails
Maybe it's late but I would like to share my method which also preserve options:
def redirect_back_or_default(default = root_path, *options)
tag_options = {}
options.first.each { |k,v| tag_options[k] = v } unless options.empty?
redirect_to (request.referer.present? ? :back : default), tag_options
end
You can use it like:
redirect_back_or_default(some_path, :notice => 'Hello from redirect', :status => 301)
Solution 6 - Ruby on-Rails
updated: Rails 5 added redirect_back method (https://github.com/rails/rails/pull/22506/), better just use:
redirect_back fallback_location: answer_path(answer), flash: { error: I18n.t('m.errors')}
For rails lower than 5.0 can still use the old way below:
similar to @troex's answer, add this to your application controller
def redirect_back_or_default(default = root_path, options = {})
redirect_to (request.referer.present? ? :back : default), options
end
then use it in your controller
redirect_back_or_default answer_path(answer), flash: { error: I18n.t('m.errors')}
Solution 7 - Ruby on-Rails
redirect_back_or_to (Rails 7+)
Rails 7 presents a new idiomatic way to redirect back or to the fallback location.
Quoting directly from the official Rails API docs:
redirect_back_or_to(fallback_location, allow_other_host: true, **args)
> Redirects the browser to the page that issued the request (the referrer) if possible, otherwise redirects to the provided default fallback location.
> The referrer information is pulled from the HTTP Referer (sic) header on the request. This is an optional header and its presence on the request is subject to browser security settings and user preferences. If the request is missing this header, the fallback_location will be used.
redirect_back_or_to({ action: "show", id: 5 })
redirect_back_or_to @post
redirect_back_or_to "http://www.rubyonrails.org"
redirect_back_or_to "/images/screenshot.jpg"
redirect_back_or_to posts_url
redirect_back_or_to proc { edit_post_url(@post) }
redirect_back_or_to '/', allow_other_host: false
It is also worth mentioning that
the Rails 5 way redirect_back(fallback_location: '/things/stuff')
has exactly the same behavior as newly introduced redirect_back_or_to('/things/stuff')
.
Sources:
- Pull Request.
redirect_back_or_to
official docs.redirect_back
official docs.
Solution 8 - Ruby on-Rails
Recently, I encountered the same issue where either I had to redirect :back
or to specific page. After going to a lot of solution, I finally found this which is simple and seems to solve the issue:
if request.env["HTTP_REFERER"].present?
redirect_to :back
else
redirect_to 'specific/page'
end
If you want to use session
details, do it in the else part of the code.