Lavavelで論理削除を実現する方法

こんにちは、さるまりんです。

データを物理的に削除するのではなくフラグのようなものを使って削除したようにする「論理削除」これをLaravelでやってみたいと思います。
データベースに既にあるテーブルに変更を加えていきます。テーブルは商品を格納するproductsとします。

1. マイグレーションファイルの作成

コマンドを実行してマイグレーションファイルを作成します。

php artisan make:migration add_deleted_at_to_products --table=products

2. マイグレーションでカラムdeleted_atを追加

前の手順で作成されたマイグレーションファイルで以下のようにカラムdeleted_atを追加します。

public function up()
{
    Schema::table('products', function (Blueprint $table) {
        $table->softDeletes();  // deleted_atカラムを追加
    });
}

public function down()
{
    Schema::table('products', function (Blueprint $table) {
        $table->dropSoftDeletes();  // deleted_atカラムを削除
    });
}

softDeletes()dropSoftDeletes()メソッドはそれぞれカラムdeleted_atを追加、削除します。

3. マイグレーションの実行

ファイルが用意できたらマイグレーションを実行します。

php artisan migrate

4. モデルにSoftDeletesトレイトを追加します。

モデルのファイルProduct.phpSoftDeleteトレイトを使用するように次のように修正します。

Product.php

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

class Product extends Model
{
    use SoftDeletes;

    // 追加設定があればここに!
}

これでProductに対して論理削除ができるようになります。

4. 削除を実施

Productを使って削除してみます。

$product = Product::find($id); // $idで指定されたProductを取得する。
$product->delete(); // 削除!

delete()メソッドの呼び出してカラムdeleted_atに実行時点の日時が記録されます。

5. 削除されたデータの取得

通常のProduct::get()では論理削除されたデータは取得されません。
論理削除済みのデータも含めて取得するには

$all = Product::withTrashed()->get();

とします。

withTrashed()メソッドで削除されたものを含めて取得できます。

やる機会があるかは置いておいて、論理削除済みのデータのみ取得するには

$trashed = Product::onlyTrashed()->get();

onlyTrashed()メソッドで削除されたものだけ取得できます。

6. 論理削除されたデータを復元

今度は復元です。

$product = Product::withTrashed()->find($id);
$product->restore(); // 復元!

restore()メソッドの呼び出しでカラムdeleted_atNULLに戻ります。

7. 論理削除されたデータを完全削除

これもやる機会があるかは置いておいて、論理削除済みのデータを完全削除する方法です。

$product = Product::withTrashed()->find($id);
$product->forceDelete(); // 完全削除!

forceDelete()メソッドを使うと、データをデータベースから完全削除します。
PCのゴミ箱の中身を完全に消去するのようなものでしょうか。

論理削除にしておくとデータを誤って消してしまっても、復元できるのでこちらを採用した方が安心なことがあります。
臨機応変にうまく使っていきたいと思います。

読んでくださってありがとうございました。

それではまた!