0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Eloquent のイベントをインスタンスメソッドに

Last updated at Posted at 2022-05-24

クロージャを使用したイベント定義

Eloquent モデルにイベントを直接記述する手段として、Laravel ドキュメントには「クロージャの使用」として例示されている。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * モデルの「起動」メソッド
     *
     * @return void
     */
    protected static function booted()
    {
        static::created(function ($user) {
            //
        });
    }
}

この記述で気に入らないことは、モデルインスタンスの変数が $this にならないこと。
例のようにモデルに依存した変数名にしてしまうと、同じ処理でも別のモデルへコピペできない。対策としては、せめて変数名 $self を採用することだろうけど、同一モデルの中に $this$self が混在するのはバグにつながる。

インスタンスメソッドで定義したい

最終目標はこんな感じ。
他のインスタンスメソッドと同じく $this で記述できるのでコピペが楽となる。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    trait BaseModelTrait;

    /**
     * 新規作成後のイベント
     *
     * @return void
     */
    private function onCreated()
    {
       //
    }
}

ということで、Eloquent モデルに必ず組み込むトレイトを作成して、そこに boot メソッドを定義した。

app/Modesl/BaseModelTrait.php

<?php

namespace App\Models;

trait BaseModelTrait
{
    /**
     * イベントをインスタンスメソッドに置き換える
     *
     * @return void
     */
    protected static function bootBaseModelTrait()
    {
        static::creating(function ($model) {
            if (method_exists($model, 'onCreating')) {
                $model->onCreating();
            }
        });
        static::created(function ($model) {
            if (method_exists($model, 'onCreated')) {
                $model->onCreated();
            }
        });
        static::updating(function ($model) {
            if (method_exists($model, 'onUpdating')) {
                $model->onUpdating();
            }
        });
        static::updated(function ($model) {
            if (method_exists($model, 'onUpdated')) {
                $model->onUpdated();
            }
        });
        static::saving(function ($model) {
            if (method_exists($model, 'onSaving')) {
                $model->onSaving();
            }
        });
        static::saved(function ($model) {
            if (method_exists($model, 'onSaved')) {
                $model->onSaved();
            }
        });
        static::deleting(function ($model) {
            if (method_exists($model, 'onDeleting')) {
                $model->onDeleting();
            }
        });
        static::deleted(function ($model) {
            if (method_exists($model, 'onDeleted')) {
                $model->onDeleted();
            }
        });
        /*
        static::restoring(function ($model) {
            if (method_exists($model, 'onRestoring')) {
                $model->onRestoring();
            }
        });
        static::restored(function ($model) {
            if (method_exists($model, 'onRestored')) {
                $model->onRestored();
            }
        });
        */
        static::retrieved(function ($model) {
            if (method_exists($model, 'onRetrieved')) {
                $model->onRetrieved();
            }
        });
    }
}
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?