您能否根据 around_action 过滤器中的 yield 块内发生的情况有条件地显示一条 Flash 消息?

Posted

技术标签:

【中文标题】您能否根据 around_action 过滤器中的 yield 块内发生的情况有条件地显示一条 Flash 消息?【英文标题】:Can you show a flash message conditionally on what happened inside a yield block in an around_action filter? 【发布时间】:2021-11-10 23:22:50 【问题描述】:

我想我对around_action 的工作原理有所了解,基本上将yield 之前的内容作为before_action 执行,以及在yield 作为after_action 之后发生的事情。

我想知道如果在此过程中发生错误,如何有效地处理给用户的错误和反馈,因为yield 运行块中的所有代码(在本例中,index 操作控制器)无论如何。

如何根据是否引发错误或是否执行了从错误中救援的条件来显示 Flash 消息?

问题:即使执行了错误中的rescue,也会呈现flash[:success](误导)。

控制器:

class ReportsController
  around_action :wrap_in_transaction, only: %i(index)
  rescue_from FileExportError, with: :file_export_error

  def index
    @tickets = Ticket.all
    respond_to do |format|
      format.html
      format.xlsx do
        response.headers["Content-Disposition"] = "attachment; filename=report"
      end
    end
    flash[:success] = "Success"
    update_tickets(@tickets) # rolls back if a rescue happens
    end
  end

  private

  def wrap_in_transaction
    ActiveRecord::Base.transaction do
      yield
    rescue FileExportError
      raise ActiveRecord::Rollback
    end
  end

  def file_export_error
    flash[:danger] = t(".file_export_error")

    redirect_to reports_path
  end

  def update_tickets(tickets)
    tickets.each do |ticket|
      ticket.update(status: "unpaid")
    end
  end
end

.xls.erb 如果尝试构建文件损坏的数据会引发错误:

@tickets.each do |ticket|
  if ticket.some_data.nil?
        raise FileExportError
  end
  sheet.add_row [ticket.user.full_name,
                 ticket.user.phone,
                 ...]

【问题讨论】:

【参考方案1】:

(忽略我之前的回答,我只是略读并误读了您是如何触发回滚的。)

您的代码执行以下操作:

    加载所有工单 配置响应格式 将 flash 消息设置为 Success 执行一些记录更新

在此之后的某个时候,可能会引发导出错误;这会触发 DB 事务的回滚,但 flash[:success] 分配不会回滚,因为它不是 DB 事务。为什么不尝试做一个flash[:error] 救援块而不是成功?或者在交易块中的收益之后移动成功可能会起作用?

【讨论】:

谢谢。如果我在 yield 之后移动闪光灯,它只会在我出于某种原因重新加载页面后显示。我将如何进行快速救援块? 另外,在wrap_in_transaction 方法中放置带有redirect_to 的确保会呈现“重定向过多”错误,尽管这是我看到的唯一错误。所以,我更困惑。 我在rescue 块内的成功闪存消息上使用了.discard 来解决第一个问题。我仍然没有设法找到一种方法来显示 flash 消息而不进行 redirect_to。 您可能需要对redirect_to some_path && return 进行一些更改,以确保它停止执行并重定向到所需的路径,但我也不确定是否有必要在那里指定重定向,因为它看起来像你'正在重定向到您的索引路径(当您完全删除重定向时会发生什么?)。

以上是关于您能否根据 around_action 过滤器中的 yield 块内发生的情况有条件地显示一条 Flash 消息?的主要内容,如果未能解决你的问题,请参考以下文章

您能否根据返回确定 FFmpeg 是不是正确执行?

根据输入中的每个字母过滤数组

SQL系列—— 过滤(where)

Tableau 实时更改复制

您能否通过数据框中的值组合SpatialPolygonsDataFrame中的多边形?

您能否将 Blob 存储中的 JSON 文件的全部内容放入 ADF 变量中?如果是这样,怎么做?