我必须手动执行SQL以使用TRUNCATE命令,这似乎很奇怪。 DHH正在保护我免受伤害吗?
答案 0 :(得分:10)
在某些数据库上使用TRUNCATE
不会运行触发器。对每行使用DELETE
仍会运行触发器。 TRUNCATE
也无法回滚,因此如果您在事务中执行了.destroy_all
,即使您尝试回滚,它也会清除所有数据。
所以,是的,你受到了截断效果的保护。
答案 1 :(得分:3)
假设您使用的是MySQL或Postgre而不是SQlite3(它不支持TRUNCATE
),您可以将以下方法添加到模型中。
def self.truncate
self.connection_pool.with_connection { |c| c.truncate(table_name) }
end
请注意,这不会调用ActiveRecord回调。有更好的方法可以将代码绑定到特定的数据库实现,但这甚至比自己编写SQL更好。
答案 2 :(得分:1)
TRUNCATE
有很多用例,在我看来,这里给出的答案非常不足。以Postgres为例:
TRUNCATE
在某些RDBMS中肯定是事务安全的,正如jsears所述。它可以回滚,至少在Postgres中。是不是Rails应该是数据库不可知的并允许这样的事情?TRUNCATE
还会在Postgres中执行BEFORE TRUNCATE
或AFTER TRUNCATE
次触发器。如果您希望在DELETE
触发TRUNCATE
触发器,那就是您的设计错误!TRUNCATE
执行速度远远快于DELETE
,特别是对于大型数据集,因为它只是一个简短的DDL语句。TRUNCATE
删除所有索引和表膨胀。由于这些原因,Rails不支持TRUNCATE
让我感到很疯狂。不,我不认为给出的理由是好的。
答案 3 :(得分:-3)
查看Model.destroy_all和活动记录:dependent => :破坏关系。如果您未指定:dependent => :destory,一些默认设置是将关系设置为null但不销毁记录。