person = Person.find(4123)
person.destroy #=> false
我有什么方法可以找出为什么记录没有被删除?该模型有两个验证,都仅在创建时触发。它有一个回调,但如果失败,回调不会阻塞。
我没有回溯或错误要查看。
person = Person.find(4123)
person.destroy #=> false
我有什么方法可以找出为什么记录没有被删除?该模型有两个验证,都仅在创建时触发。它有一个回调,但如果失败,回调不会阻塞。
我没有回溯或错误要查看。
更新:请参阅 Mike Slate 的答案以获得更快的解决方案:https ://stackoverflow.com/a/53872915/171183 。
我遇到了同样的问题,这就是我为弄清楚发生了什么所做的事情......
(TL;DR:底部给出的完整代码清单。)
首先,对于我要销毁的对象的类,我运行它以找出所有关联设置为dependent: :destroy
:
ary =
<MyClass>.reflect_on_all_associations.select { |a|
a.options[:dependent] == :destroy
}.map(&:name)
然后我调用了在我的对象上命名的每个关联ary
并收集了结果。这将关联名称限制为仅具有实际依赖对象的关联名称:
ary.select! { |association_name|
<my_object>.send(association_name).present?
}
然后我可以尝试销毁这些关联名称返回的每个对象以找到问题对象:
associated_objects =
ary.each_with_object([]) { |association_name, acc|
acc.concat(<my_object>.send(association_name))
}
problem_objects =
associated_objects.select { |obj| obj.destroy; obj.errors.any? }
# ...
然后我可以查看每个问题对象的错误:
problem_objects.map(&:errors)
这就是我终于看到导致破坏失败的错误的地方。从那里开始,它是一个简单的编程问题 (SMOP) 来解决这个问题。
在我的例子中,有一个before_destroy
回调阻止destroy 处理我的一个依赖对象关联。为了让以后的调试更简单,我决定开始在 Rails 日志中记录失败回调的错误(除了将错误消息添加到errors.base
)。
my_object = <your_object_here>
ary =
my_object.class.reflect_on_all_associations.select { |a|
a.options[:dependent] == :destroy
}.map(&:name)
ary.select! { |association_name| my_object.send(association_name).present? }
associated_objects =
ary.flat_map { |association_name| my_object.send(association_name) }
problem_objects =
associated_objects.select { |obj| obj.destroy; obj.errors.any? }
problem_objects.map(&:errors)
我已经遇到过几次这种情况,终于找到了一种简单的方法来确定记录没有被破坏的原因(在 Rails 5.x 中测试)。
只需将调用包装起来即可销毁!在救援块中,查看 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
此错误通常是由于dependent: :restrict_with_error
模型中指定的关联而引发的。在您的模型定义(以及相关的模型定义)中快速搜索此内容,看看是否是这种情况。
你在哪个版本的 Rails 上?在 Rails 4 中,您可以使用person.destroy!
. 如果操作失败,将显示回溯。
您应该添加一些调试信息,例如 logger.debug 并查看您的日志文件。例如 log/production.log 如果在生产模式下运行等等,你应该能够找出原因。如果没有,您可以在此处发布相关的日志文件部分(例如您正在运行的操作),我们可以为您提供帮助。