クロージャを使用したイベント定義
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();
}
});
}
}