Correctly doing redirect_to :back in Ruby on Rails when referrer is not available

Ruby on-RailsRubyHttp

Ruby 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:

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser67050View Question on Stackoverflow
Solution 1 - Ruby on-RailsharmView Answer on Stackoverflow
Solution 2 - Ruby on-RailsMirkoView Answer on Stackoverflow
Solution 3 - Ruby on-RailsMaranView Answer on Stackoverflow
Solution 4 - Ruby on-RailsCyril Duchon-DorisView Answer on Stackoverflow
Solution 5 - Ruby on-RailstroexView Answer on Stackoverflow
Solution 6 - Ruby on-Railslongkt90View Answer on Stackoverflow
Solution 7 - Ruby on-RailsMarian13View Answer on Stackoverflow
Solution 8 - Ruby on-RailsRahul GoyalView Answer on Stackoverflow