It seems strange that I have to manually execute SQL to use the TRUNCATE command. Is there something bad about it that DHH is protecting me against?
Using TRUNCATE
on some databases does not run triggers. Using DELETE
for each row will still run triggers. TRUNCATE
also cannot be rolled back, so if you did a .destroy_all
in a transaction, it would erase all the data even if you tried to rollback.
So, yes, you are being protected against the effects of truncate.
Assuming you're using MySQL or Postgre and not SQlite3 (which doesn't support TRUNCATE
), you could add the following method to your model.
def self.truncate
self.connection_pool.with_connection { |c| c.truncate(table_name) }
end
Note that this would not invoke ActiveRecord callbacks. There are better ways to do this that don't tie your code to a specific DB implementation, but even this is better than writing the SQL yourself.
There are many use cases for TRUNCATE
, and in my opinion, the answers given here are very insufficient. Using Postgres as an example:
TRUNCATE
is definitely transaction safe in some RDBMS, as already noted by jsears. It can be rolled back, at least in Postgres. Isn't Rails supposed to be db-agnostic and allow for such things?TRUNCATE
will also execute BEFORE TRUNCATE
or AFTER TRUNCATE
triggers in Postgres. If you are expecting a DELETE
trigger to fire on TRUNCATE
that's your design fault!TRUNCATE
performs far quicker than DELETE
especially for large datasets because it's a single short DDL statement.TRUNCATE
removes all index and table bloat.For these reasons it's crazy to me that Rails does not support TRUNCATE
. No, I don't think the reasons given are good ones.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With