before_destroy Rails 5 中的回调抛出(:abort),但也修改记录



在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

最新更新