Deleting all data from a table in Ruby on Rails
Tags: ruby, rails, database, beginners
Published: 2021-08-05 00:08:37

If you need to refresh your database, you might find that you need to delete every row from a specific table during development. 

That is **slow** 🐢. **Freaking slow** 🐄.

Glad Rails have many small tricks to solve everything 🌈 (but still not documented properly 😂).

There are several ways to achieve this. I will rank it from the slowest/scary/bad to the simplest and yet powerful solution.

Let's go !!!

---

## 3) Drop the whole database and bring it back up again 

We can achieve this with `rake:db:drop`, then `rake:db:setup`.

Wuuu, drop the database then create a new one, load the schema, and initialize it with the seed data.

Slow & Expensive !!! 🐢


## 2) destroy_all

Destroys the records by **instantiating each record** and **calling its `#destroy` method**. Each object's **callbacks are executed** (including `:dependent` association options). 

Records are instantiated and it invokes `before_remove`, `after_remove` , `before_destroy` and `after_destroy` callbacks.

Examples
```ruby
# 1
Person.where(sex: "male").destroy_all # 😂

# 2
class Author < ActiveRecord::Base
  has_many :books
end

author.books.size # => 3
author.books
# => [
#       #<Book id: 1, name: "Sapiens", author_id: 1>,
#       #<Book id: 2, name: "The Artist's Way", author_id: 2>,
#       #<Book id: 3, name: "Remote", author_id: 3>
#    ]

author.books.destroy_all

author.books.size # => 0
author.books      # => []

Book.find(1) # => Couldn't find Book with id=1
```

> Note: **Instantiation**, **callback execution**, and **deletion of each record** can be **time consuming** when you're removing many records at once. It generates at least one SQL `DELETE` query per record (or possibly more, to enforce your callbacks).

## 1) delete_all 👑

If you want to **delete many rows quickly**, without concern for their **associations** or **callbacks**, use `delete_all` instead.

Boot up a console and call `delete_all` on your model:

```ruby
% rails c
> Book.count
# => 1200 
> Book.delete_all
# => 1200
> Book.count
# => 0
```

Deletes the records **without instantiating the records first**, and hence **not calling the `#destroy` method** nor **invoking callbacks**. 

This is a single SQL `DELETE` statement that goes straight to the database, much more efficient than `destroy_all`.

You need to be careful on two things:

1- As `.delete_all` method does not instantiate any object hence does not provide any **callback** (`before_*` and `after_destroy` don't get triggered).

2- Be careful with relations, in particular `:dependent` rules defined on associations are not honored. Returns the number of rows affected.

```ruby
Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all
```

Both calls delete the affected posts all at once with a single `DELETE` statement. 

If you need to **destroy dependent associations** or **call your `before_*` or `after_destroy` callbacks**, use the `destroy_all` method instead.

More on [here](https://api.rubyonrails.org/classes/ActiveRecord/Associations/CollectionProxy.html#method-i-delete_all)

The end

---

resources:

[1](https://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-destroy_all) [2](https://api.rubyonrails.org/classes/ActiveRecord/Associations/CollectionProxy.html#method-i-destroy_all) [3](https://www.dxw.com/2014/04/ruby-on-rails-deleting-all-data-from-a-table/) [4](https://riptutorial.com/ruby-on-rails/example/9287/-delete-all) [5](https://stackoverflow.com/questions/5322298/deleting-all-records-in-a-database-table) [6](https://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-delete_all) [7](https://guides.rubyonrails.org/active_record_migrations.html)