人気のPHP WEBアプリケーションフレームワークLaravelのTipsを記録していきます

Laravel で データベース更新時にフックをかけて自動的に処理を行う。

● Laravel で データベース更新時にフックをかけて自動的に処理を行う。

Laravelではフックというとても便利な機能があります。
これはデータベースのデータに更新や削除などデータ操作があった際に好きな 処理を挟み込むことができます。
またトレイトも使用できますのでコントローラーから分離することもできます。

● 公式マニュアル

https://laravel.com/docs/5.8/eloquent#events

● 日本語公式マニュアル

(イベント)の項目を参照
https://readouble.com/laravel/5.8/ja/eloquent.html

Eloquentモデルは多くのイベントを発行します。creating、created、updating、updated、saving、saved、deleting、deleted、restoring、restored、retrievedのメソッドを利用し、モデルのライフサイクルの様々な時点をフックすることができます

● Traitを使ったフックの作成

一番簡単な Trait を使ったフックを紹介します。

・1. まずトレイトを作成します

/app/WebApiTrait.php

<?php
namespace App;
trait WebApiTrait
{
    public static function bootWebApiTrait()
    {
       static::created(function ($model) {
            dd( 'created hook', $model );
        });

       static::updated(function ($model) {
            dd( 'updated hook', $model );
        });

       static::deleted(function ($model) {
            dd( 'deleted hook', $model );
        });
    }
}

・2. フックをかけたいモデルから呼び出します。

Userモデルに追加してみましょう

<?php
namespace App;
use App\Notifications\UserResetPassword;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
    // ===== Trait フック(この行を追加) =====
    use WebApiTrait;
    // ===== / Trait フック(この行を追加) =====

これだけです。
これだけでDBデータに「新規登録」「更新(実際にデータ更新があった時)」「削除」
の時に dd(); が動いて、ダンプして停止します。
実際のロジックはdd() を書き換えればいいでしょう。

● クロージャを使ったフックの作成

モデルの boot()メソッド内 に次のように追加します。

        // Hook
        static::created(function ($model) {
            dd( 'created hook', $model );
        });
        static::updated(function ($model) {
            dd( 'updated hook', $model );
        });

● イベントを使ったフックの作成

既に \App\Events などにイベントが作成してある場合は

    // events
    protected $dispatchesEvents = [
        'updated' => \App\Events\MyEvent::class,
    ];

でディスパッチするだけです。簡単ですね。

● モデルに変更があったかどうかと変更があった内容取得する

updatingのフックで使用 ( $model->save() メソッド実行前)

// 変更があったかどうかの検知
$model->isDirty();    // true , false

// 変更内容
$d = $model->getDirty();    // 配列

updatedのフックで使用 ( $model->save() メソッド実行後)

// 変更があったかどうかの検知
$model->wasChanged();    // true , false

// 変更内容
$d = $model->getChanges();    // 配列
No.1573
10/04 09:52

edit