我如何找出为什么无法#destroy()记录的原因? [英] How do I find out why I couldn't #destroy() a record?

查看:103
本文介绍了我如何找出为什么无法#destroy()记录的原因?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我该如何找出未删除记录的原因?该模型有两个验证,均仅在创建时触发。它有一个回调,但是如果回调失败,回调不会阻止。

What ways do I have to find out why the record wasn't deleted? The model has two validations, both trigger on create only. It has one callback, but the callback doesn't block if it fails.

我没有回溯或要查看的错误。

I have no traceback or errors to look at.

推荐答案

更新:请参见Mike Slate的答案以获取更快的解决方案:https://stackoverflow.com/a/53872915/171183

Update: See Mike Slate's answer for a quicker solution: https://stackoverflow.com/a/53872915/171183.

我遇到了同样的问题,这就是我所做的找出正在发生的事情...

I ran into this same issue and here's what I've done to figure out what's going on...

(TL; DR:在底部给出完整的代码清单。)

(TL;DR: Complete code listing given at bottom.)

首先,对于我要销毁的对象的类,我使用它来找出所有关联设置为 dependent::destroy

First, for the class of the object I'm trying to destroy, I ran this to figure out what all associations are set as dependent: :destroy:

ary = 
  <MyClass>.reflect_on_all_associations.select { |a| 
    a.options[:dependent] == :destroy 
  }.map(&:name)

然后,我在对象上调用了以 ary 命名的每个关联,并收集了结果。这会将关联名称限制为仅实际具有依赖对象的关联名称:

Then I called each of the associations named in ary on my object and collected the results. This limits the association names to only those that actually have dependent objects:

ary.select! { |association_name| 
  <my_object>.send(association_name).present? 
}

然后我可以尝试销毁这些关联名称返回的每个对象,查找问题对象:

Then I can attempt to destroy each of the objects returned by these association names to find the problem object(s):

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? }
# ...

然后我可以查看每个问题对象的错误:

I then could look at the errors on each problem object:

problem_objects.map(&:errors)

在那儿,我终于看到了导致销毁失败的错误。从那里开始,有一个简单的编程问题(SMOP)来解决该问题。

And that's where I finally saw the error that was causing the destroy to fail. From there it was a Simple Matter Of Programming (SMOP) to fix the issue.

在我的案例中,有一个 before_destroy 回调,防止destroy在我的从属对象关联之一上工作。为了将来简化调试,我决定开始在失败的回调中将错误记录到Rails日志中(除​​了将错误消息添加到 errors.base )。

In my case, there was a before_destroy callback preventing destroy from working on one of my dependent object associations. To make this simpler to debug in the future, I've decided to start logging an error to the Rails log on failed callbacks (in addition to adding the error message to 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)

这篇关于我如何找出为什么无法#destroy()记录的原因?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆