💡

【Laravel8.x】observerでEloquentモデルのイベントをディスパッチしてみた

2022/01/03に公開

はじめに

Eloquentに用意されているobserverを利用してsaveメソッドを検知して処理を追加する方法を備忘録として紹介します

https://readouble.com/laravel/8.x/ja/eloquent.html

解消する問題

1.ログインユーザー名を取得する
2.1とモデルインスタンスに属性の配列を加えた配列を結合
3.save()メソッドで登録する

1.2の処理を更新時にも同じ処理を記述するのはイケてないのでobserverにやってもらいます

$loginUser = Auth::user()->name;

$storeData = array_merge(
    (new User())->fill($request->all())->toArray(),
    ['create_user' => $loginUser],
    ['update_user' => $loginUser],
);

$result = (new User())->fill($storeData)->save();

やり方

observerを生成

php artisan make:observer UserObserver --model=User

observerに処理を定義

  • 今回はsave()が成功した後に登録者・更新者を登録したいのでsaved()メソッドを利用

saved(User $user):$userにはsave()メソッドの結果(登録したユーザーのモデルインスタンス情報)が入ります

src/laravel/app/Observers/UserObserver.php
<?php

namespace App\Observers;

class UserObserver
{
    /**
     * Handle the user "save" event.
     *
     * @param User $user
     * @return void
     */
    public function saved(User $user): void
    {
        $loginUser = Auth::user()->name;
        $saveData = [
            'create_user' => $loginUser,
            'update_user' => $loginUser
        ];

        User::query()->where('id', $user->id)->update($saveData);
    }
}

observerAppServiceProviderで読み込む

src/laravel/app/Providers/AppServiceProvider.php
class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot(): void
    {
        User::observe(UserObserver::class);
    }
}

observerに移した処理を削る

スッキリかけました

なお、今回observerでクエリビルダでupdateしていますがsave()メソッドを利用したい場合はsaveQuietly()メソッドを利用してください

https://readouble.com/laravel/8.x/ja/eloquent.html

$result = (new User())->fill($request->all())->save();

おわりに

今回は簡単な例でobserverについて紹介しました
登録前の処理はsaving・削除前はdeleting等、イベントを検知することでビジネスロジックがスッキリ書ける場合もあるので使ってみるといいかもしれません。
この記事が参考になれば幸いです

GitHubで編集を提案

Discussion