Laravel テーブル内のデータ削除を論理削除にする

# 目的

- Laravelの機能実装で論理削除を勉強したためまとめる

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.3) |
| ハードウェア | MacBook Pro (16-inch ,2019) |
| プロセッサ | 2.6 GHz 6コアIntel Core i7 |
| メモリ | 16 GB 2667 MHz DDR4 |
| グラフィックス | AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いて導入 |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いて導入 |

# 物理削除と論理削除

- 物理削除
    - 一言で言うなら「消したいレコードを何も設定せずにdeleteメソッドやdestroyメソッドを実行してテーブルから削除する」こと
- 論理削除(Soft delete)
    - 一言でいうなら「消したいレコードのデータ本体は残すが、削除したことにする」こと

# 前提情報

- 本作業はカラム削除が物理削除(デフォルト状態)になっているものを論理削除に切り替える作業である。

# 概要

- 紹介する方法はMacに直接環境構築を行い、そのローカル開発環境にてEloquantを用いた論理削除の方法

1. マイグレーションファイルの作成
1. カラム作成
1. トレイト定義

# 詳細

1. マイグレーションファイルの作成
    1. アプリ名ディレクトリで下記を実行してマイグレーションファイルを作成する。

        ```terminal
        $ php artisan make:migration softdelete_テーブル名_table --table=テーブル名
        ```
    1. アプリ名ディレクトリ/detabase/migrations/YYYY_MM_DD_XXXXXX_softdelete_テーブル名_table.phpと言うファイルが作成される。
    1. アプリ名ディレクトリ/detabase/migrations/YYYY_MM_DD_XXXXXX_softdelete_テーブル名_table.phpを下記のように書き換える。

        ```アプリ名ディレクトリ/detabase/migrations/YYYY_MM_DD_XXXXXX_softdelete_テーブル名_table.php
        <?php
        
        use Illuminate\Database\Migrations\Migration;
        use Illuminate\Database\Schema\Blueprint;
        use Illuminate\Support\Facades\Schema;
        
        class SoftdeleteNoticesTable extends Migration
        {
            /**
             * Run the migrations.
             *
             * @return void
             */
            public function up()
            {
                Schema::table('テーブル名', function (Blueprint $table) {
                    //下記を追記
                    $table->softDeletes();
                });
            }
        
            /**
             * Reverse the migrations.
             *
             * @return void
             */
            public function down()
            {
                Schema::table('テーブル名', function (Blueprint $table) {
                    //下記を追記
                    $table->dropColumn('deleted_at');
                });
            }
        }
        ```
1. カラム作成
    1. アプリ名ディレクトリで下記を実行してマイグレートを行い必要なカラムを作成する。

        ```terminal
        $ php artisan migrate
        ```
1. カラム確認(ターミナルからの確認方法を記載するがカラムが作成されている事を確認したいだけなので方法は問わない)
    1. 下記コマンドを実行してMySQLにターミナル側からログインする。(ログインパスワードを忘れた方はこちら→[MySQL 8.0.18 のrootパスワードを忘れた時のリセット方法](https://qiita.com/miriwo/items/1880e9d2ebcfd3c0e60d))

        ```terminal
        $ mysql - u root -p
        ```
    1. 下記を実行してデータベースの一覧を取得する。

        ```mysql
        mysql> show database;
        ```
    1. データベース一覧の出力からlaravelアプリで使用しているデータベースを確認し下記を実行する。

        ```mysql
        mysql> use データベース名;
        ```
    1. 下記コマンドを実行してカラムの状況を出力する。

        ```mysql
        mysql> show columns 
            -> from マイグレーションで変更を加えたテーブル名;
        ```
    1. 下記のような記載がある事を確認する。

        ```
        | deleted_at             | timestamp       | YES  |     | NULL    |                |
        ```
1. トレイト定義
    1. マイグレーションで変更を加えたテーブルに紐づいているモデルファイルを開く。(モデルファイルはアプリ名ディレクトリ/app直下に存在する。)
    1. テーブルに紐づいているモデルファイルを開き、下記のように追記を行う。

        ```アプリ名ディレクトリ/app/モデル名.php
        <?php
        
        namespace App;
        
        use Illuminate\Database\Eloquent\Model;
        //下記を追記
        use Illuminate\Database\Eloquent\SoftDeletes;
        
        class NoticeContent extends Model
        {
            //下記を追記
            use SoftDeletes;
        }
        ```
    1. 上記までの作業が完了後、当該モデルでのdeleteメソッドやdestoryメソッドは物理削除ではなく、論理削除として扱われる。
1. 論理削除したレコードを取得
    1. 論理削除を行ったレコードも含めて取得する際は下記をコントローラなどで記載する。
    
        ```php
        $items = App\モデル名::withTreashed()->get();
        //コントローラの序盤でuseを用いてモデルを記載している場合は下記になる。
        $items = モデル名::withTreashed()->get();
        ```
    1. 論理削除を行ったレコードのみを取得する際は下記をコントローラなどで記載する。
    
        ```php
        $deleted_items = App\モデル名::onlyTreashed()->get();
        //コントローラの序盤でuseを用いてモデルを記載している場合は下記になる。
        $deleted_items = モデル名::onlyTreashed()->get();
        ```