Rails !! 注意 delete_all 的坑

tumayun for 北京多点科技股份有限公司 · 2017年07月07日 · 最后由 kafei 回复于 2017年12月21日 · 7778 次阅读
本帖已被管理员设置为精华贴

ActiveRecord 中有两个delete_all方法:

很多人都知道第一个 delete_all,后一个却没注意,我就是这种,今天踩了这个坑,给大家分享一下,避免有人继续踩坑!

两个方法的区别

文档上已经写的很清楚了

不会走 callback 流程,不会查找对象,直接拼 SQL 删除

我想当然的以为与上面的delete_all方法行为一致,确实是差不多,不会走 callback 流程,不会查找对象,直接拼 SQL。但是要注意,这里并不一定是删除,因为这里多了个dependent参数,实际上这里的delete_all会调用delete_or_nullify_all_records,根据dependent来确定是执行删除还是执行nullify

比如我在Topic model 上这么写:

has_many :views, class_name: :TopicView

然后我执行:

@topic.views.delete_all # 删除所有 views

实际上会执行与预期不符的 SQL:

UPDATE `topic_views` SET `topic_views`.`topic_id` = NULL WHERE `topic_views`.`topic_id` = 5927

这时我应该加上dependent参数,这样才能符合删除所有views的预期

@topic.views.delete_all(:delete_all) # 删除所有 views
huacnlee 将本帖设为了精华贴。 07月07日 14:34

这个问题比较有意思~之前确实没注意到....

另外 ActiveRecord::Associations::CollectionProxy作用是 The @target object is not loaded until needed.

Article.published  #Relation
Article.first.authors  #CollectionProxy
Article.first.authors.all  #Relation

前一段时间正好遇到了这个问题,当时没深入研究,原来是这样的。👍

不过 delete_all 居然也敢用。。

tony612 回复

逻辑删除后,每隔一段时间需要进行物理删除

正经的情况,db 根本就不给 rails 项目 delete 的权限...

For has_many :through associations, the default deletion strategy is :delete_all.
For has_many associations, the default deletion strategy is :nullify. This sets the foreign keys to NULL.

涨姿势了~

解除引用就行了

用 destroy_all 方法应该两种情况都能准确删除记录了吧,也不需要传递 dependent 参数。

学习了!

踩过。。。哈哈

zj0713001 回复

更糟的是 DB 不给 rails 项目建表以及修改表结构的权限,migration 被折磨的一无是处。😂

timlen 回复

我觉得限制一定的权限还是很有意义的,万一某个新手写了个 xxx migration 操作线上的数据库的时候,你想想就知道了

哇,刚来 Ruby China 就看到 tumayun!

需要 登录 后方可回复, 如果你还没有账号请 注册新账号