Перенаправление на указанный URL после POST в Rails
Очень часто у меня на веб-странице есть форма, которую пользователь отправляет в Pils, PUT или DELETE в Rails, где я хочу, чтобы она перенаправляла на указанный URL, если отправка прошла успешно. Я обычно делаю скрытый дополнительный параметр под названием to
с пути как /users
, Таким образом, если отправка формы не удалась, она просто остается в этой форме, но если это происходит успешно, браузер перенаправляется на /users
,
Я хотел бы автоматически искать этот параметр и всегда перенаправлять его, если отправка формы прошла успешно в каком-либо контроллере / действии. Я положу это в ApplicationController
в пределах after_action
?
class ApplicationController < ActionController::Base
after_action :redirect_if_success
private
def redirect_if_success
redirect_to params[:to] if params[:to]
end
end
Я думаю, я могу проверить объект запроса, если это было действие POST, PUT или DELETE. Как я знаю, что представление было успешным? Будет redirect_to
в after_action
переопределить любой redirect_to
в форме контроллера?
2 ответа
Я думаю, что решение заключается в том, чтобы определить частный метод redirect_if_success в контроллере приложения, но вызвать его непосредственно в действии. например:
class ApplicationController < ActionController::Base
private
def redirect_if_success(default_ur)
redirect_to params[:to] || default_url
# or similar logic
end
end
class UserController < ApplicationController::Base
def create
redirect_if_success("/users") if @user.save
end
end
Я бы создал вспомогательный метод
def redirect_to_location
redirect_to params[:to] && params[:to].present?
end
и я бы использовал это явно в каждом действии, я хочу это поведение.
Тем не менее, вы могли бы немного поэкспериментировать. Чтобы сохранить эту логику в after_action, вам нужно установить какое-то состояние, которое сообщит вам, нужно ли вам перенаправить или нет.
Вы могли бы сделать:
def save
if @user.save
@follow_redirect = true
end
end
и проверьте флаг @follow_redirect в фильтре after_action. Не похоже на очень красивое решение, но оно будет работать.
Вы также можете попытаться проверить переменную ответа, чтобы увидеть, перенаправили ли вы уже или оказали действие: (не уверен, что оно будет работать, но интересно поэкспериментировать)
Так что вы можете проверить:
если вам нужно перенаправить (действие post/put/delete) и params[:to] присутствует и если вы еще не перенаправили / перенаправили
# this is not a copy-paste code but rather to demonstrate an idea
class ApplicationController < ActionController::Base
after_action :redirect_to_location
protected
def is_redirectable?
%w{post put delete}.include?(request.method) && params[:to].present?
end
def already_redirected?
!response.status.nil? # not sure if it would work at all
end
def redirect_to_location
redirect_to params[:to] if is_redirectable? && !already_redirected?
end
end