【问题标题】:Rails - How to break out of a controller method?Rails - 如何突破控制器方法?
【发布时间】:2023-01-12 09:11:36
【问题描述】:

我在控制器中有一个更新方法。如果 params[:single] 的值为 1,我想运行一个如下所示的 create_exception 方法而不更新记录:

  before_action :create_exception, only: %i[ update ]

  def update
    if @event.update(event_params) ...
  end

  private

  def create_exception
    if params[:single] == 1
      @exception = @event.event_exceptions.create(date: params[:exception_date])
      respond_to do |format|
        format.turbo_stream
        format.html { redirect_to events_path, notice: "Event was successfully updated." }
        format.json { head :no_content }
      end
    end
  end

我的第一个问题是,当我更新事件时,create_exception 方法似乎没有触发。它只是调用更新并更新记录上的信息,这不是我想要的。如果 params[:single] = 1 我想创建一个期望并重定向回计划而不更新事件。

完成此任务的最佳方法是什么?

【问题讨论】:

  • 传递的参数将是一个字符串,而不是一个整数。将 params[:single] == 1 更改为 params[:single] == '1'
  • 我总是喜欢params[:single].to_i
  • 谢谢。我已经尝试了这两个选项,但仍然没有捕捉到这一点。如果我检查 params,我会看到 params[:single] 确实等于 1。如果我从异常创建中删除 if 检查,它会起作用并创建异常/重定向。出于某种原因,如果签入,它没有正确地看到该参数来执行该方法。
  • 您可以分享请求日志中的参数吗?

标签: ruby-on-rails


【解决方案1】:

来自指南:

redirect_to 和 redirect_back 不会停止并立即从方法执行中返回,而是简单地设置 HTTP 响应。方法中出现在它们之后的语句将被执行。如果需要,您可以通过显式返回或其他某种停止机制来停止。

它还说:

如果“之前”过滤器呈现或重定向,则不会运行该操作。如果有其他过滤器计划在该过滤器之后运行,它们也会被取消。

所以我认为问题是,鉴于您向我们展示的代码,它只会在遇到 format.html { redirect_to events_path, notice: "Event was successfully updated." } 时停止执行

您是否正在使用 HTML 请求访问此控制器? format: turbo_streamformat: json 没有进行任何重定向,因此它们不会停止操作的执行。如果您正在发出常规 HTML 请求,那么您可以将一些 Web 控制台代码添加到您的问题中以进行进一步的故障排除吗?

【讨论】:

    【解决方案2】:

    参数值总是字符串,所以检查params[:single] == "1"


    before_action 对于在操作运行之前应该普遍发生的事情很有用,比如检查权限。

    它不应该用于改变单个动作的行为。那就是远距离行动。

    相反,请检查更新方法中的参数和return early

      def update
        return create_event_exception if params[:single] == "1"
    
        # update as normal
      end
    
      private
    
      def create_event_exception
          @exception = @event.event_exceptions.create(date: params[:exception_date])
          respond_to do |format|
            format.turbo_stream
            format.html { redirect_to events_path, notice: "Event was successfully updated." }
            format.json { head :no_content }
          end
      end
    

    update 的完整行为是清楚的,它不依赖于读者了解 before_action 如何工作的细节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多