Rails - 在before_destroy回调时取消销毁

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rails - 在before_destroy回调时取消销毁相关的知识,希望对你有一定的参考价值。

有什么办法,在某些条件下,取消对活动记录的before_destroy回调中的对象的销毁?谢谢

答案

你应该返回false

Rails 5

“取消回调

如果before_ *回调抛出:abort,则取消所有后续回调和相关操作。“

Rails 4 and lower

“取消回调

如果before_ *回调返回false,则取消所有后续回调和相关操作。回调通常按照定义的顺序运行,但定义为模型上的方法的回调除外,这些回调最后被称为。

Source

另一答案

Rails包装在事务中保存和销毁,因此回调中的raise可以工作:

class Post < ActiveRecord::Base
  before_destroy :saveable?

  def saveable?
    if true
      raise "Destroy aborted; you can't do that!"
    end
  end
end

替换true为您的条件。

这是删节控制台输出:

[1] pry(main)> Post.first.id
=> 1
[2] pry(main)> Post.first.destroy
RuntimeError: Destroy aborted; you can't do that!
[3] pry(main)> Post.first.id
=> 1

Documentation

另一答案

返回false是正确的方法:

before_destroy do
  if self.some_condition?
    return false
  end
end

你可以在点6 Halting Execution下看到这里的文档。 http://guides.rubyonrails.org/active_record_callbacks.html

另一答案

由于没有一个给定的答案真正解决了问题,但上面的评论告诉它 - 这里以答案的形式使其易于查找:

在轨道5中,而不是

before_destroy do
  if self.some_condition?
    return false
  end
end

使用

before_destroy do
  if self.some_condition?
    throw(:abort)
  end
end

确保不进行破坏。

感谢RFVoltolini's comment - 这节省了我的一天!

另一答案

您还可以覆盖#destroy方法:

def destroy
  study_assignments.empty? ? super : self
end

以上是关于Rails - 在before_destroy回调时取消销毁的主要内容,如果未能解决你的问题,请参考以下文章

在相关模型更新销毁之前,错误不会传播

在 Rails 中为域逻辑使用回调的优缺点

什么时候在 Rails 回调链中分配 Postgres 中的默认值?

如何在 Rails 中实现 Paypal 回调? (获取 InvalidAuthenticityToken 错误)

在 Rails 控制器操作上设置多个回调

rails回调未得到执行