🐼
Laravel Observerを使ってみた
はじめに
Laravel 10のEloquentで提供されるObserverはモデルにおいてCRUD処理などを行う際に、毎回実行される処理を設定することができるので便利。
Observerの設定
Observerの生成
app/Observersフォルダ配下に生成される
php artisan make:observer UserObserver --model=User
作成されたObserverファイルの中身。生成時に指定したmodelがベースになっている
UserObserver.php
<?php
namespace App\Observers;
use App\Models\User;
class UserObserver
{
/**
* Handle the User "created" event.
*/
public function created(User $user): void
{
//
}
/**
* Handle the User "updated" event.
*/
public function updated(User $user): void
{
//
}
/**
* Handle the User "deleted" event.
*/
public function deleted(User $user): void
{
//
}
/**
* Handle the User "restored" event.
*/
public function restored(User $user): void
{
//
}
/**
* Handle the User "force deleted" event.
*/
public function forceDeleted(User $user): void
{
//
}
}
Observerの登録
モデルのobserveメソッドを呼び出す。
App\Providers\EventServiceProvider.php
use App\Models\User;
use App\Observers\UserObserver; // 追加
/**
* Register any events for your application.
*/
public function boot(): void
{
User::observe(UserObserver::class); // 追加
}
再利用できるObserverの設定
複数モデルで利用した場合の例
ファイル作成
App\Observers\FooBarObserver.php
<?php
namespace App\Observers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class FooBarObserver
{
/**
* @param Model $model
* @return void
*/
public function creating(Model $model)
{
if (Auth::user()) {
$model->created_by = Auth::user()->id;
$model->updated_by = Auth::user()->id;
}
}
/**
* @param Model $model
* @return void
*/
public function updating(Model $model)
{
//
}
/**
* @param Model $model
* @return void
*/
public function saving(Model $model)
{
//
}
/**
* @param Model $model
* @return void
*/
public function deleting(Model $model)
{
//
}
}
設定
boot{トレイト名}で作っておくとクラス呼び出し時に書かれた処理が行われる。
(\Illuminate\Database\Eloquent\Model::bootTraits
がうまいことやってくれるようだ)
App\Traits\FooBarTrait.php
<?php
namespace App\Traits;
use App\Observers\FooBarObserver;
trait FooBarTrait
{
public static function bootFooBarTrait()
{
static::observe(FooBarObserver::class);
}
}
利用するモデルでロード
App\Models\Foo
<?php
namespace App\Models;
use App\Traits\FooBarTrait; // 追加
use Illuminate\Database\Eloquent\Model;
class Foo extends Model
{
use FooBarTrait; // 追加
}
Eventメソッド
メソッド名の違い
creating(現在進行形):モデルがDBに保存される前に実行される
created (過去形):モデルがDBに保存される前に実行される
DBトランザクション
DBトランザクションがコミットされた後に変更を加えたい場合、ShouldHandleEventsAfterCommit
インターフェースを利用できる。
UserObserver.php
<?php
namespace App\Observers;
use App\Models\User;
use Illuminate\Contracts\Events\ShouldHandleEventsAfterCommit; // 追加
class UserObserver implements ShouldHandleEventsAfterCommit // ここ
{
/**
* Handle the User "created" event.
*/
public function created(User $user): void
{
//
}
}
課題
Model::insertには効かなかった問題の調査
OK
$user = new User;
$user->name = $request->name,
$user->email = $request->email,
$user->save();
NG
$users = [
['name' => 'Pikachu', 'email' => 'pikachu@example.com'],
['name' => 'Eevee', 'email' => 'eevee@example.com'],
];
User::insert($users);
参考
Observer
Event
Discussion