1

So often I have a form in some webpage that the user submits to a POST, PUT or DELETE action in Rails where I want it to redirect to a specified URL if the submission was a success. I typically make a hidden extra parameter called to with a path like /users. So if the form submission failed, it just stays on that form, but if it succeeds then the browser is redirected to /users.

I'd like to automatically look for this parameter and always redirect to it if a form submission succeeded in any controller/action. Do I put this in the ApplicationController within an 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

I guess I can check the request object if this was a POST, PUT or DELETE action. How do I know the submission was a success? Will a redirect_to in the after_action override any redirect_tos in the form controller?

4

2 回答 2

0

我会创建一个辅助方法

def redirect_to_location
  redirect_to params[:to] && params[:to].present?
end

我会在我想要这种行为的每个动作中明确使用它。

但是,您可以尝试一下。要将此逻辑保留在 after_action 中,您需要设置一些状态,让您知道是否需要重定向。

你可以这样做:

def save
  if @user.save
    @follow_redirect = true
  end
end

并检查 after_action 过滤器中的 @follow_redirect 标志。看起来不是一个非常漂亮的解决方案,但它会起作用。

您还可以尝试检查响应变量以查看您是否已经重定向或呈现了一个动作:(不确定它是否会起作用,但试验很有趣)

所以你可以检查:

如果您需要重定向(操作是 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
于 2013-10-24T16:55:24.863 回答
0

我认为解决方案是在应用程序控制器中定义私有方法 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
于 2013-10-24T16:32:31.083 回答