#10 Laravel基礎

ソフトデリートとオブザーバー

ソフトデリートとは

ソフトデリート? データを物理的に消さず「削除済み」フラグを立てるだけの削除方法。間違えて消してもデータを復元できる。 は、データをデータベースから物理的に削除せず「削除済みフラグ」を立てるだけの削除方法です。deleted_at カラムに削除日時が入り、通常のクエリでは自動的に除外されます。

誤操作で消したデータを復元できるのが最大のメリットです。


ソフトデリートの設定

① マイグレーションに deleted_at カラムを追加

<?php
// 📁 database/migrations/xxxx_create_posts_table.php

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('body');
    $table->timestamps();
    $table->softDeletes(); // ← deleted_at カラムを追加
});

② モデルに SoftDeletes トレイトを追加

<?php
// 📁 app/Models/Post.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; // ← インポート

class Post extends Model
{
    use SoftDeletes; // ← トレイトを使用
}

これだけで設定完了です。


基本の操作

// 削除(deleted_at に現在時刻が入る、物理削除はされない)
$post = Post::find(1);
$post->delete();

// 通常の取得(削除済みは自動で除外)
$posts = Post::all(); // deleted_at IS NULL のみ

// 削除済みも含めて取得
$allPosts = Post::withTrashed()->get();

// 削除済みだけを取得
$trashedPosts = Post::onlyTrashed()->get();

// 復元
$post = Post::withTrashed()->find(1);
$post->restore();

// 物理削除(完全に消す)
$post->forceDelete();

オブザーバーとは

オブザーバー? モデルの作成・更新・削除などのイベントをまとめて監視するクラス。モデル操作に連動した処理を書くのに使う。 は、モデルのイベント(作成・更新・削除など)に反応する処理を1つのクラスにまとめる仕組みです。

例えば「投稿が作成されたらSlackに通知」「ユーザーが削除されたら関連データも掃除」などの処理をオブザーバーに書けます。


オブザーバーを生成する

php artisan make:observer PostObserver --model=Post

app/Observers/PostObserver.php が生成されます。

<?php
// 📁 app/Observers/PostObserver.php

namespace App\Observers;

use App\Models\Post;

class PostObserver
{
    // 投稿が作成された後に呼ばれる
    public function created(Post $post): void
    {
        // 例:作成者にメール通知
        // Mail::to($post->user)->send(new PostCreatedMail($post));
    }

    // 投稿が更新された後に呼ばれる
    public function updated(Post $post): void
    {
        // 例:キャッシュを削除
        // Cache::forget("post:{$post->id}");
    }

    // 投稿が削除される前に呼ばれる
    public function deleting(Post $post): void
    {
        // 例:関連する画像ファイルを削除
        // Storage::delete($post->thumbnail_path);
    }

    // 投稿が復元された後に呼ばれる
    public function restored(Post $post): void
    {
        //
    }
}

オブザーバーを登録する

// 📁 app/Providers/AppServiceProvider.php

use App\Models\Post;
use App\Observers\PostObserver;

public function boot(): void
{
    Post::observe(PostObserver::class);
}

利用可能なイベント

メソッド名発火タイミング
creating保存前(新規作成)
created保存後(新規作成)
updating保存前(更新)
updated保存後(更新)
saving保存前(新規・更新両方)
saved保存後(新規・更新両方)
deleting削除前
deleted削除後
restoring復元前
restored復元後

creatingupdatingfalse を返すと処理を中断できます。


モデルイベントをスキップする

パフォーマンス上の理由でオブザーバーを発火させたくない場合:

// オブザーバーを発火させずに保存
Post::withoutEvents(function () {
    Post::factory()->count(1000)->create();
});

まとめ

  • SoftDeletes トレイトと softDeletes() マイグレーションで論理削除が使える
  • delete()deleted_at を埋めるだけ。forceDelete() が物理削除
  • withTrashed(), onlyTrashed(), restore() で削除済みデータを操作できる
  • オブザーバーはモデルのライフサイクルイベントをまとめて管理する場所
  • AppServiceProviderPost::observe() を呼ぶだけで登録できる

次回はマイグレーションの応用(カラム変更・インデックス・複合ユニーク)を学びます。