【问题标题】:Redirect to a specified URL after a POST in Rails在 Rails 中的 POST 之后重定向到指定的 URL
【发布时间】:2013-10-24 16:16:49
【问题描述】:

我经常在某些网页中有一个表单,用户提交到 Rails 中的 POST、PUT 或 DELETE 操作,如果提交成功,我希望它重定向到指定的 URL。我通常会创建一个名为to 的隐藏额外参数,其路径类似于/users。因此,如果表单提交失败,它只会停留在该表单上,但如果成功,则浏览器将重定向到 /users

如果表单提交在 any 控制器/操作中成功,我想自动查找此参数并始终重定向到它。我是否将其放在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 操作,我想我可以检查请求对象。我怎么知道提交是否成功? after_action 中的 redirect_to 会覆盖表单控制器中的任何 redirect_tos 吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3.2 ruby-on-rails-4 actioncontroller applicationcontroller


    【解决方案1】:

    我认为解决方案是在应用程序控制器中定义私有方法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
    

    【讨论】:

      【解决方案2】:

      我会创建一个辅助方法

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-08
        • 2010-11-02
        • 1970-01-01
        • 1970-01-01
        • 2011-09-02
        • 2022-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多