LaravelのEloquentにはObserverという仕組みがあります。ObserverはEloquentのイベント発生によって発火するメソッドの集まりです。
Eloquent:利用の開始 6.0 Laravel#オブザーバ
Observerは次のようにartisanでボイラープレート的なモノを生成できます。
php artisan make:observer UserObserver --model=User
以下の様に生成されたクラスをLaravelの起動時処理で登録することによってイベント監視が動作します。
<?php
namespace App\Providers;
use App\Observers\UserObserver;
use App\User;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
//省略
/**
* 全アプリケーションサービスの初期起動
*
* @return void
*/
public function boot()
{
User::observe(UserObserver::class); // ここでモデル::observe(オブザーバクラス::class)が基本
Post::observe([PostObserver::class, BBSObserver::class); // 複数でもOK
foreach (['Post', 'Comment'] as $className) {// 共通のオブザーバを使うならこんな書き方もあり
/* @var Eloquent $className */
$className::observe(UpdateTalkedAtObserver::class);
}
}
}
オブザーバの使い時は色々あります。例えば、ある集約全体における更新日時を記録する場合です。
LaravelのEloquentにはタイムスタンプを自動記録する機能があり、あるレコードを更新した際にそのレコード内の特定のカラム(デフォはupdated_at)に日時を記録してくれます。これだけでも便利なのですが、これだけではシステムの要求を満たせない場合もあります。例えば、あるユーザの情報が複数テーブルに分割されており、いずれかの情報が更新された時にユーザ情報が更新されたとし、その更新日時を記録する必要がある、という場合です。より具体的に次のER図のテーブル構成があるとします。

ブログへの投稿かコメントを行った時にユーザの最終発言日時を記録する、とします。このような時、次のObserverを作ると要求を満たせます。
class UpdateTalkedAtObserver
{
public function created(Eloquent $postOrComment) // 宣言した型に依らず、登録したEloquentクラスのインスタンスが渡される
{
$postOrComment->user->talked_at = $postOrComment->created_at;
$postOrComment->user->save();
}
public function updated(Eloquent $postOrComment) // 宣言した型に依らず、登録したEloquentクラスのインスタンスが渡される
{
$postOrComment->user->talked_at = $postOrComment->updated_at;
$postOrComment->user->save();
}
}
他にもログ取り、検索テーブル用の同期、削除や復元の連鎖など使うと楽になる場面がいくらかあります。また単にモデルのコードが膨れ上がらないための分割としても使えます。