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