Rails !! 注意 delete_all 的坑

tumayun for 北京多点科技股份有限公司 · 发布于 2017年07月07日 · 最后由 fadeaway 回复于 2017年08月12日 · 3941 次阅读
967
本帖已被设为精华帖!

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
共收到 14 条回复
De6df3 huacnlee 将本帖设为了精华贴 07月07日 14:34
3444

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

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

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

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

1232

不过 delete_all 居然也敢用。。

967
1232tony612 回复

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

3753

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

10351

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.

涨姿势了~

9800

解除引用就行了

28365

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

1704

学习了!

2329

踩过。。。哈哈

29416

学习了

16895
3753zj0713001 回复

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

15420
16895timlen 回复

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

7be631

哇,刚来 Ruby China 就看到 tumayun!

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