Last Updated: January 23, 2019
·
16.45K
· Marko Klemetti

Redirect to back or default in Rails

What happens if your user user cannot access a resource in your application? Do you redirect the user back to the previous page?

redirect_to :back

Unfortunately :back depends on the request header variable HTTP_REFERER, and thus you might run into trouble if it does not exist. This might be the case if your user is for example trying to access the resource with a direct link (e.g. a bookmark or a link from an email).

Instead you should extract the back-functionality, and create a common method for redirection with an extra fallback:

def redirect_to_back_or_default(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

And then use it in your controllers instead of the redirect_to :back like so:

def show
  ...
  redirect_to_back_or_default
  ...
end

Now your user is redirected to the root_url (changeable with the default-parameter) if HTTP_REFERER does not exist.

You should also remember the other formats and give an error message instead of the redirection:

respond_to do |format|
  format.html { redirect_to_back_or_default }
  format.json { render json:
    {errors: [I18n.t("some.error.message")]}, status: 404
  }
end

See redirect_to in Rails API documentation

3 Responses
Add your response

Wanted to make a small amendment. Add *args so that you can pass through other options like notices.

def redirect_to_back_or_default(default = root_url, *args)
  if request.env['HTTP_REFERER'].present? && request.env['HTTP_REFERER'] != request.env['REQUEST_URI']
    redirect_to :back, *args
  else
    redirect_to default, *args
  end
end
over 1 year ago ·

why do you have to check 'request.env["HTTPREFERER"] != request.env["REQUESTURI"]'? Don't know when they would be equal.

thanks

over 1 year ago ·

This check 'request.env["HTTPREFERER"] != request.env["REQUESTURI"]' is required to avoid multiple calls to the same url.

over 1 year ago ·