[Laravel]Eloquentで論理削除を使う方法

Laravel

Eloquentで論理削除を使う方法

LaravelのEloquentを使用して、論理削除をする方法を記載しています。
マイグレーションを作成して、論理削除の設定を追加して、実際に削除を試してみました。

Laravelのバージョン8で動作確認しています。

論理削除を含めたテーブルをマイグレーションする

マイグレーションを作成する

テスト用のテーブルとして、membersテーブルを作成します。

新しくテーブルとモデルを作成してみました。

$ php artisan make:model Member --migration
Model created successfully.
Created Migration: 2020_10_13_012146_create_members_table

ファイルはdatabase/migrations/[作成日]_create_members_table.phpに保存されます。

作成されたマイグレーションファイルは下記になります。
このファイルのupメソッドを修正して、カラムの追加と論理削除の設定をします。

class CreateMembersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('members', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('members');
    }
}

マイグレーションを修正する

レコードを論理削除にしたい場合は、テーブルを作成するマイグレーションにsoftDeletesメソッドをつける必要があります。

migrationに、このようにsoftDeletesメソッドを入れることによって、論理削除可能なテーブルになります。

    public function up()
    {
        Schema::create('members', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->boolean('gender');
            $table->integer('age');
            $table->string('address');
            $table->string('tel');
            $table->softDeletes();
            $table->timestamps();
        });
    }

この状態に編集したらmigrateを実行します。

$ php artisan migrate
Migrating: 2020_10_13_012146_create_members_table
Migrated:  2020_10_13_012146_create_members_table (5.99ms)

すると、下記のようになります。(sqliteでスキーマを表示させました)

CREATE TABLE IF NOT EXISTS "members"(
    "id" integer not null primary key autoincrement,
    "name" varchar not null,
    "gender" tinyint(1) not null,
    "age" integer not null,
    "address" varchar not null,
    "tel" varchar not null,
    "deleted_at" datetime null,
    "created_at" datetime null,
    "updated_at" datetime null
)
;

softDeletesメソッドを呼ぶことにより、deleted_atのカラムが作成されました。
これが論理削除のフラグの役割をして、削除日付が入っていたら「削除されている」ということになります。

論理削除を使うようにモデルを修正する

作成したモデルを論理削除を使用するように修正します。
use SoftDeletesを入れることで、論理削除が使用されるようになります。

class Member extends Model
{
    use HasFactory;
    use SoftDeletes;
    protected $fillable = [
        'name',
        'gender',
        'age',
        'address',
        'tel'
    ];
}

動作確認する

下記のデータを作成しました。

idnamegenderageaddressteldeleted_atcreated_atupdated_at
1testuser69033住所ホゲホゲ48090-1234-24122020-10-13 01:51:282020-10-13 01:51:28
2testuser7054住所ホゲホゲ91090-1234-58292020-10-13 01:51:292020-10-13 01:51:29
3testuser5071住所ホゲホゲ23090-1234-44932020-10-13 01:51:302020-10-13 01:51:30

2番目のデータをEloquentのdeleteメソッドで削除します。

Member::find(2)->delete();

論理削除のカラムに日付が入って、削除されたことになります。

idnamegenderageaddressteldeleted_atcreated_atupdated_at
1testuser69033住所ホゲホゲ48090-1234-24122020-10-13 01:51:282020-10-13 01:51:28
2testuser7054住所ホゲホゲ91090-1234-58292020-10-13 01:52:162020-10-13 01:51:292020-10-13 01:52:16
3testuser5071住所ホゲホゲ23090-1234-44932020-10-13 01:51:302020-10-13 01:51:30

これで、通常通りデータを取得した場合は下記のようになります。

dd(Member::all()->toArray());

ddで全てのレコードを出力すると…

array:2 [▼
  0 => array:9 [▼
    "id" => 1
    "name" => "testuser69"
    "gender" => "0"
    "age" => "33"
    "address" => "住所ホゲホゲ48"
    "tel" => "090-1234-2412"
    "deleted_at" => null
    "created_at" => "2020-10-13T01:51:28.000000Z"
    "updated_at" => "2020-10-13T01:51:28.000000Z"
  ]
  1 => array:9 [▼
    "id" => 3
    "name" => "testuser5"
    "gender" => "0"
    "age" => "71"
    "address" => "住所ホゲホゲ23"
    "tel" => "090-1234-4493"
    "deleted_at" => null
    "created_at" => "2020-10-13T01:51:30.000000Z"
    "updated_at" => "2020-10-13T01:51:30.000000Z"
  ]
]

論理削除されているものは取得されないようになりました。

削除したものは論理削除のカラムに日付が入って、
データ取得時にはLaravelが無視して、データを取得してくれるようになります。

Eloquentの論理削除に関連するメソッド

論理削除されているレコードを含めて取得する

withTrashedメソッドを使うと、取得できます。
こうすると、論理削除を含めた全てのレコードが、Collectionにモデルが入った形で返ってきます。

Member::withTrashed()->get();

論理削除されているレコードのみ取得する

onlyTrashedメソッドを使うと、取得できます。
こうすると、論理削除されたレコードのみがCollectionにモデルが入った形で返ってきます。

Member::onlyTrashed()->get();

論理削除されているレコードの復元

restoreメソッドで復元できます。
こうすると、削除されているid=2のデータを復元します。

テーブルのdeleted_atは空になります。

Member::onlyTrashed()->whereId(2)->restore();

コメント

タイトルとURLをコピーしました