Как перенаправить на предыдущую страницу в Ruby On Rails? - PullRequest
178 голосов
/ 26 января 2010

У меня есть страница со списком всех проектов с сортируемыми заголовками и нумерацией страниц.

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

Я выбираю для редактирования один из проектов

path:
projects/436/edit

Когда я нажимаю сохранить на этой странице, он вызывает контроллер проекта / метод обновления. После того, как я обновлю код, я хочу перенаправить на путь, по которому я был, прежде чем я щелкнул редактировать конкретный проект. Другими словами, я хочу быть на той же странице с той же сортировкой.

Я видел link_to (: back) и думал, что: back может работать в redirect_to (: back), но это не пойдет.

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

Любые идеи о том, как я могу заставить это работать. Это похоже на проблему, которую легко решить, но я новичок в RoR.

Ответы [ 7 ]

316 голосов
/ 26 января 2010

В вашем действии редактирования сохраните запрашивающий URL в хеше сеанса, который доступен для нескольких запросов:

session[:return_to] ||= request.referer

Затем перенаправьте на него в действии обновления после успешного сохранения:

redirect_to session.delete(:return_to)
96 голосов
/ 13 февраля 2011

Почему redirect_to(:back) у вас не работает, почему нет?

redirect_to(:back) работает как шарм для меня. Это просто короткий путь для redirect_to(request.env['HTTP_REFERER'])

http://apidock.com/rails/ActionController/Base/redirect_to (до Rails 3) или http://apidock.com/rails/ActionController/Redirecting/redirect_to (Rails 3)

Обратите внимание, что redirect_to(:back) устарела в Rails 5. Вы можете использовать

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

45 голосов
/ 21 октября 2010

Мне нравится метод Хайме с одним исключением, для меня лучше работать каждый раз, когда я заново сохраняю реферер:

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

Причина в том, что если вы редактируете несколько объектов, вы всегда будете перенаправлены обратно на первый URL-адрес, который вы сохранили в сеансе с помощью метода Jaime. Например, допустим, у меня есть объекты Apple и Orange. Я редактирую Apple, и session[:return_to] устанавливается для реферера этого действия. Когда я иду редактировать Апельсины, используя тот же код, session[:return_to] не будет установлен, потому что он уже определен. Поэтому, когда я обновлю Orange, меня отправят рефереру предыдущего действия Apple # edit.

33 голосов
/ 27 января 2010

Вот как мы это делаем в нашем приложении

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

Таким образом вы сохраняете последний GET-запрос только в :return_to параметре сеанса, поэтому все формы, даже если многократный POSTed будет работать с :return_to.

18 голосов
/ 25 марта 2011

request.referer устанавливается Rack и устанавливается следующим образом:

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

Просто введите redirect_to request.referer, и он всегда будет перенаправлен на страницу с истинной ссылкой или путь root_path ('/'). Это важно при прохождении тестов, которые терпят неудачу в случаях прямой навигации к определенной странице, на которой контроллер выдает redirect_to: back

14 голосов
/ 03 июля 2016

В рельсах 5, согласно инструкциям в Rails Guides, вы можете использовать:

redirect_back(fallback_location: root_path)

Местоположение 'back' берется из заголовка HTTP_REFERER, который не гарантируется браузером. Вот почему вы должны предоставить 'fallback_location'.

1 голос
/ 08 ноября 2016

Для тех, кто заинтересован, вот моя реализация, расширяющая оригинальный ответ MBO (написанный против 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...