Как перенаправить на предыдущую страницу в Ruby On Rails?
У меня есть страница, в которой перечислены все проекты, у которых есть сортируемые заголовки и разбиение на страницы.
path:
/projects?order=asc&page=3&sort=code
Я хочу изменить один из проектов
path:
projects/436/edit
Когда я нажимаю "Сохранить" на этой странице, он вызывает метод контроллера/обновления проектов. После того, как я обновляю код, я хочу перенаправить на тот путь, который был включен до того, как я щелкнул, отредактировав конкретный проект. Другими словами, я хочу быть на одной странице с той же сортировкой.
Я видел link_to (: назад) и думал, что: back может работать в redirect_to (: back), но это не идет.
puts YAML::dump(:back)
yields the following:
:back
Любые идеи о том, как я могу заставить это работать. Это похоже на проблему, которую легко решить, но я новичок в RoR.
Ответы
Ответ 1
В вашем действии редактирования сохраните запрашивающий URL-адрес в хэше сеанса, который доступен для нескольких запросов:
session[:return_to] ||= request.referer
Затем перенаправляйте его в действие обновления после успешного сохранения:
redirect_to session.delete(:return_to)
Ответ 2
Почему redirect_to(:back)
не работает для вас, почему это не так?
redirect_to(:back)
работает как прелесть для меня. Это просто короткое сокращение для
redirect_to(request.env['HTTP_REFERER'])
http://apidock.com/rails/ActionController/Base/redirect_to (pre 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)
Ответ 3
Мне нравится метод Хайме, за одним исключением, мне лучше было пересобирать реферирования каждый раз:
def edit
session[:return_to] = request.referer
...
Причина в том, что если вы редактируете несколько объектов, вы всегда будете перенаправлены обратно на первый URL, который вы сохранили в сеансе, с помощью метода Хайме. Например, допустим, у меня есть объекты Apple и Orange. Я редактирую Apple, а session[:return_to]
устанавливается в референт этого действия. Когда я перехожу к редактированию апельсинов с использованием того же кода, session[:return_to]
не будет установлен, потому что он уже определен. Поэтому, когда я обновляю Orange, меня отправят референту предыдущего действия Apple # edit.
Ответ 4
Так мы делаем это в нашем приложении
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
.
Ответ 5
request.referer
устанавливается Rack и устанавливается следующим образом:
def referer
@env['HTTP_REFERER'] || '/'
end
Просто выполните redirect_to request.referer
, и он всегда будет перенаправлен на настоящую страницу ссылок или корневой путь ('/'). Это важно при передаче тестов, которые не выполняются при непосредственном наступлении на конкретную страницу, на которой контроллер выдает redirect_to: back
Ответ 6
В рельсах 5, в соответствии с инструкциями в Rails Guides, вы можете использовать:
redirect_back(fallback_location: root_path)
Местоположение "назад" вытаскивается из заголовка HTTP_REFERER, который не гарантируется установкой браузером. Вот почему вы должны предоставить "fallback_location".
Ответ 7
Для тех, кого это интересует, вот моя реализация, расширяющая исходный ответ MBO (написанный против рельсов 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