【Rails】destroy_allメソッドの使い方を徹底解説!

Rails

destroy_allメソッドとは

すでにテーブルに存在するレコードを一括で削除するメソッドです。

destroy_allメソッドの使い方

destroy_allメソッドの構文

ターミナル
1
モデルクラスまたはインスタンス.destroy_all

このように記述するとテーブル内の全てのレコードが一括で削除されます。

実際にdestroy_allメソッドを使ってみよう

それでは実際にdestroy_allメソッドを使ってみましょう。
usersテーブルの全てのレコードを削除したいときは下記のように記述します。

ターミナル
1
User.destroy_all

またwhereメソッドと併用すると条件に当てはまったレコードを一括で削除することができます。

ターミナル
1
2
# idが1から10のレコードを一括で削除
User.where(id: 1..10).destroy_all
ターミナル
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[1] pry(main)> User.where(id: 1..10).destroy_all
   (0.4ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
  User Load (1.5ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` BETWEEN 1 AND 10
   (0.3ms)  BEGIN
  User Destroy (0.4ms)  DELETE FROM `users` WHERE `users`.`id` = 1
   (0.8ms)  COMMIT
   (0.1ms)  BEGIN
  User Destroy (0.2ms)  DELETE FROM `users` WHERE `users`.`id` = 2
   (0.3ms)  COMMIT
   (0.1ms)  BEGIN
  User Destroy (0.2ms)  DELETE FROM `users` WHERE `users`.`id` = 3
   (0.3ms)  COMMIT
   (0.1ms)  BEGIN
  User Destroy (0.2ms)  DELETE FROM `users` WHERE `users`.`id` = 4
   (0.5ms)  COMMIT
   (0.1ms)  BEGIN
  User Destroy (0.4ms)  DELETE FROM `users` WHERE `users`.`id` = 5
   (0.3ms)  COMMIT
   (0.1ms)  BEGIN
  User Destroy (0.4ms)  DELETE FROM `users` WHERE `users`.`id` = 6
   (0.4ms)  COMMIT
   (0.1ms)  BEGIN
  User Destroy (0.2ms)  DELETE FROM `users` WHERE `users`.`id` = 7
   (0.3ms)  COMMIT
   (0.1ms)  BEGIN
  User Destroy (0.2ms)  DELETE FROM `users` WHERE `users`.`id` = 8
   (0.2ms)  COMMIT
   (0.1ms)  BEGIN
  User Destroy (0.4ms)  DELETE FROM `users` WHERE `users`.`id` = 9
   (0.3ms)  COMMIT
   (0.1ms)  BEGIN
  User Destroy (1.3ms)  DELETE FROM `users` WHERE `users`.`id` = 10
   (6.2ms)  COMMIT

またはアソシエーションを使って関連するレコードを削除することもできます。

ターミナル
1
2
3
# idが1のユーザーの投稿を一括で削除
user = User.find(1)
user.articles.destroy_all

この場合userのレコードは削除されません。
削除されるのはarticlesテーブルのレコードだけです。

ターミナル
1
2
3
4
5
6
7
8
9
[1] pry(main)> user = User.find(1)
[2] pry(main)> user.articles.destroy_all
  Article Load (0.6ms)  SELECT `articles`.* FROM `articles` WHERE `articles`.`user_id` = 1
   (0.4ms)  BEGIN
  Article Destroy (0.8ms)  DELETE FROM `articles` WHERE `articles`.`id` = 1
  Article Destroy (0.2ms)  DELETE FROM `articles` WHERE `articles`.`id` = 4
  Article Destroy (25.6ms)  DELETE FROM `articles` WHERE `articles`.`id` = 6
  Article Destroy (0.8ms)  DELETE FROM `articles` WHERE `articles`.`id` = 10
   (0.7ms)  COMMIT

delete_allメソッドとの違い

destroy_allメソッドはデータを削除するときにActiveRecord、つまりモデルを介すのに対し、delete_allメソッドはActiveRecordを介さずにSQLを直接実行してデータを削除します。

ですので、モデルでdependentオプションを定義していてもdelete_allはモデルを介さないので、「dependentオプション」は実行されません。

※dependentオプションについてはdestoryメソッドの記事を参照してください

全てのレコードを削除するボタンを作ってみよう

実際のアプリではほとんど作成することはないかと思いますが、練習としてdestroy_allメソッドを使って全てのレコードを削除するボタンを作ってみましょう。

今回はdestroy_allアクションを追加します。
ルーティングを下記のように編集します。

collectionを使いrailsの7つのアクション以外のアクションをルーティングに追加します。
collectionについてはresourcesメソッドの記事を参照してください。

routes.rb
1
2
3
4
5
resources :articles do
  collection do
    delete 'destroy_all'
  end
end

次にarticlesコントローラーにdestroy_allアクションを定義します。

articlesコントローラー
1
2
3
4
def destroy_all
  Article.destroy_all
  redirect_to articles_path
end

次にビューファイルに全て削除するボタンを作成します。
今回はbutton_toメソッドを使いボタンを作成します。

articles/index.html.erb
1
<%= button_to "全て削除", destroy_all_articles_path, method: :delete %>

これで全ての記事を削除する機能が実装できました。
実際にボタンを押してみましょう。

destroy_all

このように一括でレコードを削除することができました。

一つ一つレコードを削除するのが面倒なときにdestroy_allメソッドを使ってみましょう。

まとめ

・destroy_allメソッドはレコードを一括で削除するときに使用するメソッドです。
・モデルを介して削除を実行します。
・モデルを介さないときはdelete_allメソッドを使います。