You know the drill: some invalid data pops up in the production database and you have to get rid of it. You fire up your Rails console on the production server and type in the query:
Foo.where(bar: 'baz').all
You review the returned data and it's what you need to remove. Then you type:
Foo.where(bar: 'baz').destroy_all
And your heart stops for a second. You just want to see the query before it runs.
Is there any way to do that in Rails? I'm looking for a method similar to
Foo.where(bar: 'baz').to_sql
but the one that will return the DELETE query.
destroy_all(conditions = nil) Destroys the records matching conditions by instantiating each record and calling its destroy method. Each object's callbacks are executed (including :dependent association options and before_destroy/after_destroy Observer methods).
Rails Delete operation using delete method Unlike the destroy method, with delete, you can remove a record directly from the database. Any dependencies to other records in the model are not taken into account. The method delete only deletes that one row in the database and nothing else.
The destroy method, destroys the records matching conditions by instantiating each record. It returns a collection of objects which they are destroyed, but the returned objects will be frozen so that no changes could be made on it. They execute callbacks and :dependent rules.
Rails provides an ActiveRecord method called :includes which loads associated records in advance and limits the number of SQL queries made to the database. This technique is known as "eager loading" and in many cases will improve performance by a significant amount.
The problem is that destroy_all
does not run a single SQL query. It iterates through a hash of objects, instantiates them, runs their callbacks, and then calls that object's destroy
method. Rails has no built-in way of producing an array of these queries.
Cdesroisiers is right that you can test the query in sandbox mode, but the real problem is that you're second-guessing your decision to run delete_all
, even though you've verified whatever data is being targeted.
Consider using an ActiveRecord versioning gem like PaperTrail if you're not willing to trust ActiveRecord to properly delete objects.
Just off the top of my head, you could run the console in sandbox mode and run the delete query to see the sql. The changes would just be rolled back on exit.
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