Rails - 在before_destroy回调时取消销毁

时间:2016-06-14 19:50:36

标签: ruby-on-rails activerecord

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

5 个答案:

答案 0 :(得分:22)

您应该返回false

Rails 5

“取消回调

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

Rails 4及以下

“取消回调

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

Source

答案 1 :(得分:3)

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

答案 2 :(得分:3)

返回false是正确执行此操作的方法:

before_destroy do
  if self.some_condition?
    return false
  end
end

您可以在点6 Halting Execution下看到此处的文档。 http://guides.rubyonrails.org/active_record_callbacks.html

答案 3 :(得分:2)

由于给出的答案都不能真正解决问题,但是上面的注释说明了这一点-这里的答案形式很容易找到:

在Rails 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-这挽救了我的一天!

答案 4 :(得分:1)

您还可以覆盖#destroy方法:

def destroy
  study_assignments.empty? ? super : self
end