model:prune — 未使用モデルを削除するコマンド

artisan

Laravel Artisan コマンド:model:prune

要点(TL;DR)

何をするか 実行例 重要なオプション
定義済み Prunable ロジックを実行し、不要レコードを削除 php artisan model:prune --force, --dry-run, --model

警告
本番環境で --force を付けずに実行すると、確認プロンプトで停止します。
--dry-run は削除件数のみ表示し、実際にレコードは削除されません。


1. 概要

model:prune は Laravel 9 で導入された Artisan コマンドで、Eloquent モデルに public function prunable(): Builder を実装した「削除対象」を自動でクリーンアップします。
コマンド実行時に各モデルの prunable() を呼び出し、返却されたクエリビルダーで取得したレコードを delete() で一括削除します。


2. コマンドシグネチャ

php artisan model:prune [options] [--model=]...
オプション 必須 既定値 説明
--force bool いいえ false 確認プロンプトをスキップ
--dry-run bool いいえ false 削除件数を表示のみ(実際は削除しない)
--model string[] いいえ [] 指定モデルのみを対象(複数可)
--except string[] いいえ [] 指定モデルを除外

戻り値

int – 削除件数(--dry-run でも削除件数を返す)。


3. 実務での使い方

3.1 典型的なユースケース

例:30日以上非アクティブなユーザーを削除

// app/Models/User.php
use Illuminate\Database\Eloquent\Prunable;
use Illuminate\Support\Carbon;

class User extends Model
{
    use Prunable;

    public function prunable()
    {
        return static::where('last_login_at', '<', Carbon::now()->subDays(30));
    }
}
# まず削除件数を確認
php artisan model:prune --dry-run
# => 200 件が削除対象です

# 本番で削除
php artisan model:prune --force
# => 200 件が削除されました

3.2 モデル限定で実行

php artisan model:prune --model=User --model=Post

3.3 除外モデルを指定

php artisan model:prune --except=ArchivedUser

4. 代替手段との比較

手段 メリット デメリット
Model::query()->where(...)->delete() 条件自由度が高い 逐次削除で遅い
php artisan db:wipe テーブル全体をリセット すべてのデータが消える
model:prune 一括安全削除、トランザクション内 prunable() の実装が必要

5. よくある落とし穴

症状 原因 対処
コマンドが停止 本番環境で --force を付け忘れ --force を追加
削除件数がゼロ prunable() の条件ミス 条件を確認し --dry-run で検証
大量削除時にタイムアウト 一度に大量レコードを削除 --model で対象を限定、またはバッチ処理を自前実装
削除が意図しないテーブルへ影響 prunable() に結合クエリを含めた 参照整合性を確認、必要なら onDelete('cascade') を設定

6. テスト例(Pest)

it('prunes old users', function () {
    User::factory()->create(['last_login_at' => now()->subDays(40)]);
    User::factory()->create(['last_login_at' => now()]);

    $this->artisan('model:prune')
         ->expectsOutput('1 record(s) deleted.')
         ->assertExitCode(0);

    expect(User::count())->toBe(1);
});

7. 参考リンク


レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする