我如何找出为什么我不能#destroy()记录?

时间:2013-05-27 06:23:37

标签: ruby-on-rails activerecord

person = Person.find(4123)
person.destroy #=> false

我有哪些方法可以找出未删除记录的原因?该模型有两个验证,都只在创建时触发。它有一个回调,但如果失败则回调不会阻止。

我没有回溯或错误。

5 个答案:

答案 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如果在生产模式等运行,你应该能够找到原因。如果没有,您可以在此处发布相关的日志文件部分(例如您正在运行的操作),我们可以帮助您。