Перенаправление на указанный URL-адрес после POST в Rails

Очень часто у меня есть форма на какой-нибудь веб-странице, которую пользователь отправляет в действие POST, 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
person Armando    schedule 24.10.2013

Я бы создал вспомогательный метод

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
person Tumas    schedule 24.10.2013