How to redirect to previous page in Ruby On Rails?

Ruby on-RailsRedirect

Ruby on-Rails Problem Overview


I have a page that lists all of the projects that has sortable headers and pagination.

path:
/projects?order=asc&page=3&sort=code

I choose to edit one of the projects

path:
projects/436/edit

When I click save on that page, it calls the projects controller / update method. After I update the code I want to redirect to the path that I was on before I clicked edit a specific project. In other words, I want to be on the same page with the same sorting.

I saw link_to(:back) and thought that :back may work in redirect_to(:back), but that's a no go.

puts YAML::dump(:back) 
yields the following:
:back 

Any ideas on How I could get this to work. It seems like a problem that would be easily solved, but I'm new to RoR.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

In your edit action, store the requesting url in the session hash, which is available across multiple requests:

session[:return_to] ||= request.referer

Then redirect to it in your update action, after a successful save:

redirect_to session.delete(:return_to)

Solution 2 - Ruby on-Rails

Why does redirect_to(:back) not work for you, why is it a no go?

redirect_to(:back) works like a charm for me. It's just a short cut for redirect_to(request.env['HTTP_REFERER'])

http://apidock.com/rails/ActionController/Base/redirect_to (pre Rails 3) or http://apidock.com/rails/ActionController/Redirecting/redirect_to (Rails 3)

Please note that redirect_to(:back) is being deprecated in Rails 5. You can use

redirect_back(fallback_location: 'something') instead (see http://blog.bigbinary.com/2016/02/29/rails-5-improves-redirect_to_back-with-redirect-back.html)

Solution 3 - Ruby on-Rails

I like Jaime's method with one exception, it worked better for me to re-store the referer every time:

def edit
    session[:return_to] = request.referer
...

The reason is that if you edit multiple objects, you will always be redirected back to the first URL you stored in the session with Jaime's method. For example, let's say I have objects Apple and Orange. I edit Apple and session[:return_to] gets set to the referer of that action. When I go to edit Oranges using the same code, session[:return_to] will not get set because it is already defined. So when I update the Orange, I will get sent to the referer of the previous Apple#edit action.

Solution 4 - Ruby on-Rails

This is how we do it in our application

def store_location
  session[:return_to] = request.fullpath if request.get? and controller_name != "user_sessions" and controller_name != "sessions"
end

def redirect_back_or_default(default)
  redirect_to(session[:return_to] || default)
end

This way you only store last GET request in :return_to session param, so all forms, even when multiple time POSTed would work with :return_to.

Solution 5 - Ruby on-Rails

In rails 5, as per the instructions in Rails Guides, you can use:

redirect_back(fallback_location: root_path)

The 'back' location is pulled from the HTTP_REFERER header which is not guaranteed to be set by the browser. Thats why you should provide a 'fallback_location'.

Solution 6 - Ruby on-Rails

request.referer is set by Rack and is set as follows:

def referer
  @env['HTTP_REFERER'] || '/'
end

Just do a redirect_to request.referer and it will always redirect to the true referring page, or the root_path ('/'). This is essential when passing tests that fail in cases of direct-nav to a particular page in which the controller throws a redirect_to :back

Solution 7 - Ruby on-Rails

For those who are interested, here is my implementation extending MBO's original answer (written against rails 4.2.4, ruby 2.1.5).

class ApplicationController < ActionController::Base
  after_filter :set_return_to_location

  REDIRECT_CONTROLLER_BLACKLIST = %w(
    sessions
    user_sessions
    ...
    etc.
  )

  ...

  def set_return_to_location
    return unless request.get?
    return unless request.format.html?
    return unless %w(show index edit).include?(params[:action])
    return if REDIRECT_CONTROLLER_BLACKLIST.include?(controller_name)
    session[:return_to] = request.fullpath
  end

  def redirect_back_or_default(default_path = root_path)
    redirect_to(
      session[:return_to].present? && session[:return_to] != request.fullpath ?
        session[:return_to] : default_path
    )
  end
end

Solution 8 - Ruby on-Rails

link_to 'get me back', :back

The symbol :back is your swiss army knife.

Solution 9 - Ruby on-Rails

I wonder if this will work

  def edit
    if request.referer != request.original_url
        @return_here =  request.referer
    end

  end

and use @return_here as a hidden value in the submit form.

of course reloading will kill this so just go back to a default fall back as needed.

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
QuestioneasementView Question on Stackoverflow
Solution 1 - Ruby on-RailsJaime BellmyerView Answer on Stackoverflow
Solution 2 - Ruby on-RailsPascalView Answer on Stackoverflow
Solution 3 - Ruby on-RailsTonyView Answer on Stackoverflow
Solution 4 - Ruby on-RailsMBOView Answer on Stackoverflow
Solution 5 - Ruby on-RailspSkarlView Answer on Stackoverflow
Solution 6 - Ruby on-RailsSteve TiptonView Answer on Stackoverflow
Solution 7 - Ruby on-RailsaschyielView Answer on Stackoverflow
Solution 8 - Ruby on-RailsJeromeView Answer on Stackoverflow
Solution 9 - Ruby on-RailsgekongView Answer on Stackoverflow