callback - Rails 5 throw(:abort) 中的 before_destroy 回调,但也修改了记录
问题描述
在 Rails 5 中,我相信防止破坏的唯一方法是调用throw(:abort)
; 这正在按预期工作。但是,我遇到的问题是,如果记录不符合要求,而不是销毁它,我想修改记录。然而,throw(:abort)
整个事务被还原,撤消记录收到的任何更改。
关于如何实现这一目标的任何建议?
class Thing < ApplicationRecord
before_destroy :can_destroy?
private
def can_destroy?
if model.something?
self.update(something: 'foo') # This part is not being retained.
throw(:abort)
end
end
解决方案
您遇到的问题是 ActiveRecord 将所有之前/之后的回调包装在事务中,以确保如果其中任何一个失败,则不会将任何结果提交给数据库。可悲的是,你想做的正是它试图保护你免受伤害的事情。这样做并没有真正的“好”方法(我知道),但是绕过这个限制的一些技巧是在after_rollback
回调中进行更新,因为你throw(:abort)
会导致事务回滚。例如:
class Thing < ApplicationRecord
before_destroy :can_destroy?
after_rollback :can_destroy_callbacks
private
def can_destroy?
if model.something?
@update_later = true
throw(:abort)
end
end
def can_destroy_callbacks
if @update_later
update(something: 'foo')
end
end
end