Laravel(6.x) 削除フラグはいらない、ソフトデリートを使ってレコードを論理削除する

Laravelにはソフトデリートという論理削除をするための機能が備わっています
delete_flag、is_deleted … などテーブルに用意している人はいませんか?
(そもそも論理削除という機能をもたせるかどうかは置いておいて…)

migrationファイルを作成する

まずはテーブル作成用ファイルを作成します
例として記事用テーブルを作成します(複数形を指定します)

php artisan make:migration create_articles_table --create=articles

/プロジェクト名/database/migrations/の下に新しいmigrationファイルが作成されます

ソフトデリートを記述する

作成されたmigrationファイルを以下のように修正します

ポイントは softDeletes() を追加している点です
これを書くだけで論理削除用につかうカラムが作成されます

    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->text('contents');
            $table->timestamps();

            $table->softDeletes();
        });
    }

テーブルを作成する

migrationファイルができたのでmigrationを実行してテーブルを作成します

php artisan migrate

テーブルが作成されたら、mysqlに入ってテーブル定義を確認してみます

mysql> desc articles;
+------------+---------------------+------+-----+---------+----------------+
| Field      | Type                | Null | Key | Default | Extra          |
+------------+---------------------+------+-----+---------+----------------+
| id         | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| contents   | text                | NO   |     | NULL    |                |
| created_at | timestamp           | YES  |     | NULL    |                |
| updated_at | timestamp           | YES  |     | NULL    |                |
| deleted_at | timestamp           | YES  |     | NULL    |                |
+------------+---------------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)

softDeletes() を追加したことでテーブルには deleted_at のカラムが追加されます
これが論理削除に使われるカラムになります

論理削除のやり方

カラムができたので実際にモデルを作成して論理削除してみます

モデル作成

php artisan make:model Article

モデルに以下を追加します
SoftDeletesのTraitを利用することを記述します

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Article extends Model
{
    use SoftDeletes;
}

テーブルにデータを用意します

mysql> select * from articles;
+----+--------------+---------------------+---------------------+------------+
| id | contents     | created_at          | updated_at          | deleted_at |
+----+--------------+---------------------+---------------------+------------+
|  1 | ほげほげ     | 2020-10-30 19:42:13 | 2020-10-30 19:42:13 | NULL       |
+----+--------------+---------------------+---------------------+------------+

論理削除する

上記のデータを対象に論理削除を実行します
Modelを以下のように実行します
※destroyメソッドですが、固定なので引数なしにしています

ポイントは、find()のあとのdelete()です

    public function destroy()
    {
        Article::find(1)->delete();
        return;
    }

これでデータを再度確認してみます

mysql> select * from articles;
+----+--------------+---------------------+---------------------+---------------------+
| id | contents     | created_at          | updated_at          | deleted_at          |
+----+--------------+---------------------+---------------------+---------------------+
|  1 | ほげほげ     | 2020-10-30 19:42:13 | 2020-10-30 19:50:22 | 2020-10-30 19:50:22 |
+----+--------------+---------------------+---------------------+---------------------+

deleted_atに削除を実行した日時が保存されました
もし、ModelにTraitを実装していない場合、delete()メソッドを実行すると
レコード削除されます(物理削除)

まとめ

Laravelには細かなところまで用意されていますね
今回は論理削除(ソフトデリート)の紹介でした