为什么ActiveRecord has_many使用delete_all而不是destroy_all?
我有一个有很多孩子的模型。我这样设置/删除子项:
mymodel.children_ids = [1,2,3]
mymodel.save #add the children
mymodel.children_ids = [1]
mymodel.save #remove children 2,3
这工作得很好,但我刚刚意识到没有在子项模型上调用任何回调(即 after_destroy
)。
经过一番挖掘,发现正在执行的是 delete_all
函数,而不是 destroy_all
。正如文档正确指出的那样,delete_all 函数不会触发回调,那么有没有办法改变这种行为呢?
谢谢。
I have a model which has many children. I was setting/removing the children as such:
mymodel.children_ids = [1,2,3]
mymodel.save #add the children
mymodel.children_ids = [1]
mymodel.save #remove children 2,3
This works just fine, but I just realized that none of the callbacks (i.e. after_destroy
) are not being called on the children model.
After some digging, it turns out that the delete_all
function is being executed, rather than destroy_all
. As the docs correctly state, the delete_all
function does not fire off the callbacks, so is there anyway to change this behavior?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
比如:
会完成这项工作。这不完全是你想要的,但我希望它有帮助。
Something like:
will do the job. It's not exactly what you wanted, but I hope it helps.
delete_all
正在执行...只是因为? Rails 核心团队认为在这种情况下应该这样称呼。但是,您可以对模型的子项显式调用destroy_all
方法,但不使用该类型的查询。看起来您是直接设置子 ID,而不是使用任何build()
或destroy()
方法。是的,您可以覆盖其功能。您可以对其进行修补并将其放入
/vendor
中,并使用destroy_all
重写相同的代码块。然后使用send
命令将基本 ActiveRecord 功能替换为您自己的功能。delete_all
is being executed... just because? That's what the Rails core team thought should be called in that instance. However, you could explicitly call thedestroy_all
method on the model's children, but not using that type of query. It looks like you're setting the child IDs directly, not using anybuild()
ordestroy()
methods.Yes, you can overwrite its functionality. You could patch it and put it in
/vendor
, rewriting the same block of code withdestroy_all
instead. Then use asend
command to replace the base ActiveRecord functionality with your own.对于那些感兴趣的人,我添加了以下 Monkeypatch 来强制 has_many 通过执行 destroy_all,而不是 delete_all。可能有更好的方法,所以我愿意接受建议。
For those interested, I added the following monkeypatch to force the has_many through to perform a destroy_all, rather than delete_all. There might be a better way, so I'm open to suggestions.
我在回调方面也遇到了类似的问题。使用 alias_method_chain 覆盖默认设置器解决了这个问题。
有关alias_method_chain的更多详细信息:
http://yehudakatz.com/2009/03/ 06/alias_method_chain-in-models/
I had similar problem with callbacks. Solved it using alias_method_chain to override default setter.
More details on alias_method_chain:
http://yehudakatz.com/2009/03/06/alias_method_chain-in-models/