Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to preview a delete_all or destroy_all query in Rails

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.

like image 641
Damir Zekić Avatar asked Jun 07 '12 16:06

Damir Zekić


People also ask

Does Destroy_all trigger callbacks?

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).

What is the difference between delete and destroy in Rails?

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.

What does Destroy_all return?

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.

What are .includes in Rails?

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.


2 Answers

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.

like image 160
rpedroso Avatar answered Oct 06 '22 00:10

rpedroso


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.

like image 20
cdesrosiers Avatar answered Oct 06 '22 01:10

cdesrosiers