您能否根据 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 消息?的主要内容,如果未能解决你的问题,请参考以下文章