Laravelで論理削除を実装する場合、以下のようにマイグレーションファイルを作成します
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTopicsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('topics', function (Blueprint $table) {
$table->id();
$table->boolean('is_draft')->default(true)->comment('下書きフラグ 管理者が設定する true: 下書き, false: 公開');
$table->boolean('is_published')->default(false)->comment('公開フラグ バッチが自動設定する true: 公開, false: 非公開');
$table->string('title')->comment('タイトル');
$table->text('body')->comment('本文');
$table->date('published_at')->nullable()->comment('公開日');
$table->boolean('send_email')->default(false)->comment('メール送信フラグ 顧客に一斉送信するかどうか true: 送信する, false: 送信しない');
$table->softDeletes('deleted_at');
$table->timestamps();
});
}
モデルに use SoftDelete
を追加します
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Topic extends Model
{
use HasFactory;
use SoftDeletes;
/**
* 日付を変形する属性
*
* @var array
*/
protected $dates = [
'published_at',
'created_at',
'updated_at',
];
}
SoftDeletes を指定している場合、 Topic::where('is_draft', true)->delete();
のように削除処理を実行しても、テーブルの deleted_at
カラムに削除日時が登録されるだけで、データは消えません。これを論理削除といいます。
「deleted_at
がnullではない場合、システム内では消したことにする」という処理を実装しています。
ここで、たまに論理削除を適用しているテーブルであっても、物理的に消してしまいたい!ということがあります。例えば、この例で使っている Topic テーブルの下書きデータは、1カ月放置していたら物理削除してしまいたい場合もあるでしょう。
そんなときは、 forceDelete()
を使います。
Topic::where('is_draft', true)->where('updated_at', '<=', now()->subMonth())->forceDelete();
これでテーブルからデータがきれいに消えました。ただこの場合、一度削除すると復元できませんので、注意が必要です。
参考 Laravel 12.x Eloquentの準備
https://readouble.com/laravel/12.x/ja/eloquent.html