更新:请参阅 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)