person = Person.find(4123)
person.destroy #=> false
我有哪些方法可以找出未删除记录的原因?该模型有两个验证,都只在创建时触发。它有一个回调,但如果失败则回调不会阻止。
我没有回溯或错误。
答案 0 :(得分:30)
我遇到了同样的问题,这就是我为了弄清楚发生了什么而做的......
首先,对于我想要销毁的对象的类,我运行这个以找出所有关联被设置为dependent: :destroy
的内容:
ary = Klass.reflect_on_all_associations
.select { |a| a.options[:dependent] == :destroy }
.map(&:name)
然后我在我的对象上调用ary
中命名的每个关联并收集结果。这会将关联名称限制为仅包含实际具有依赖对象的名称:
ary.select! { |a| obj.send(a).any? }
然后我可以尝试销毁这些关联名称返回的每个对象:
destroy_me = obj.send(ary[0]).first
destroy_me.destroy
我只有一个对象,所以上面的内容足以导致破坏失败。然后,我可以查看未能销毁的对象上的错误:
destroy_me.errors
这就是我终于看到导致破坏失败的错误的地方。从那里开始,它是一个简单的编程问题(SMOP)来解决这个问题。
在我的情况下,有一个before_destroy
回调阻止销毁我的一个依赖对象关联。为了使将来调试变得更加简单,我决定在失败的回调中开始将错误记录到Rails日志中(除了将错误消息添加到errors.base
)。
答案 1 :(得分:2)
您使用的是什么版本的Rails?在Rails 4中,您可以使用person.destroy!
强制销毁。如果操作失败,将显示回溯。
答案 2 :(得分:2)
由于在模型中的关联上指定了dependent: :restrict_with_error
,通常会引发此错误。在模型定义(以及相关的模型定义)中快速搜索此内容,看看是否属实。
答案 3 :(得分:1)
我已经遇到过几次了,终于遇到了一种简单的方法来确定记录未被破坏的原因(在Rails 5.x中进行了测试)。
只需将对 destroy!的调用包装在救援块中,然后查看error.record.errors。
begin
person = Person.find(4123)
person.destroy! #=> Note the exclamation mark which will cause an error if it fails
rescue ActiveRecord::RecordNotDestroyed => error
puts "errors that prevented destruction: #{error.record.errors}"
end
答案 4 :(得分:0)
您应该添加一些调试信息,例如logger.debug并查看您的日志文件。例如log / production.log如果在生产模式等运行,你应该能够找到原因。如果没有,您可以在此处发布相关的日志文件部分(例如您正在运行的操作),我们可以帮助您。