ホームページ  >  記事  >  PHPフレームワーク  >  Laravelでモデルイベントを使用する方法について話しましょう

Laravelでモデルイベントを使用する方法について話しましょう

青灯夜游
青灯夜游転載
2022-12-22 21:42:011584ブラウズ

Laravelでモデルイベントを使用する方法について話しましょう

Eloquent モデルを使用する場合、モデルのライフサイクルを通じてディスパッチされるイベントを利用するのが一般的です。これを行うにはいくつかの異なる方法があり、このチュートリアルではそれらを取り上げ、それぞれの長所と短所を説明します。 [関連する推奨事項: laravel ビデオ チュートリアル ]

直接比較できるように、各メソッドに同じ例を使用します。この例では、モデル自体の作成中に、モデルの UUID プロパティを UUID に割り当てます。

最初のアプローチでは、モデルの静的ブートストラップ メソッドを使用して動作を登録します。これにより、モデルを直接操作し、モデルの作成時にモデルを作成できるようになります。

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Office extends Model
{
    public static function boot(): void
    {
        static::creating(fn (Model $model) =>
            $model->uuid = Str::uuid(),
        );
    }
}

このアプローチは、非常に理解しやすく、モデルで何が起こっているかを正確に確認できるため、UUID の追加など、モデル イベントに対する小規模で直接的な反応に最適です。このアプローチの最大の問題はコードの重複です。UUID を割り当てる必要があるモデルが複数ある場合、同じことを繰り返し行うことになります。

これにより、機能を使用する 2 番目のアプローチにうまくつながります。 Laravel では、boot で始まりトレイト名で終わるトレイトのメソッドを作成すると、モデルはトレイトを継承して自動的に開始できます。以下に例を示します。

declare(strict_types=1);

namespace App\Models\Concerns;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

trait HasUuid
{
    public static function bootHasUuid(): void
    {
        static::creating(fn (Model $model) =>
            $model->uuid = Str::uuid(),
        );
    }
}

トレイトを使用すると、この動作を必要とするすべてのモデルにこの動作を追加でき、実装が簡単になります。私の最大の欠点は、複数の機能が同じモデル イベントを利用したい場合に、これらの動作を積み重ねると問題が発生する可能性があることです。彼らは優先順位をめぐって争い始め、すぐに混乱してしまいます。

これにより、次のオプションであるモデル オブザーバーが表示されます。モデル オブザーバーは、モデル イベントに応答するクラスベースの方法であり、メソッドはトリガーされた特定のイベントに対応します。

declare(strict_types=1);

namespace App\Observers;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class OfficeObserver
{
    public function creating(Model $model): void
    {
        $model->uuid = Str::uuid();
    }
}

このクラスは、サービス プロバイダーまたはモデル自体のどこかに登録する必要があります (これをお勧めします)。このオブザーバーをモデルに登録すると、雄弁な動作の変化による副作用をモデル レベルで確認できるようになります。サービスプロバイダーからそれを隠す場合の問題は、誰もがその存在を知らない限り、それを知るのが難しいことです。このアプローチの最大の欠点は、その可視性です。私の意見では、この方法は正しく使えば素晴らしいものです。

この問題を解決するもう 1 つの方法は、Eloquent モデル自体の $dispatchesEvents プロパティを利用することです。これは、すべての Eloquent モデルのプロパティであり、リッスンするイベントと、それらのイベントに対して呼び出すクラスをリストすることができます。

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Office extends Model
{
    protected $dispatchesEvents = [
        'creating' => SetModelUuid::class,
    ];
}

SetModelUuid は、Eloquent モデルのライフ サイクル中にインスタンス化されます。これは、モデルに動作とプロパティを追加する機会となります。

declare(strict_types=1);

namespace App\Models\Events;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class SetModelUuid
{
    public function __construct(Model $model)
    {
        $model->uuid = Str::uuid();
    }
}

このアプローチは、モデルの可視性が高く、このクラスをモデル間で簡単に共有できるため、最もクリーンで理解しやすいアプローチの 1 つです。直面する最大の疑問は、モデル イベントに対して複数のアクションをトリガーする必要があるかどうかです。

とにかく、正直に言って、これを行う正しい方法はありません。上記の方法のいずれかを選択でき、すべて機能しますが、自分と特定の使用例に適した方法を選択する必要があります。この特定の機能に関するオプションをもっと増やしてほしいと思います。

たとえば、モデル イベントでモデルに複数のプロパティを追加する必要がある場合は、オブザーバーが適しています。しかし、これが最善の選択肢でしょうか?このモデルのカスタム パイプラインを実行するためにディスパッチ イベント属性を使用するとどうなるでしょうか?

declare(strict_types=1);

namespace App\Models\Pipelines;

use App\Models\Office

class OfficeCreatingPipeline
{
    public function __construct(Office $model)
    {
        app(Pipeline::class)
            ->send($model)
            ->through([
                ApplyUuidProperty::class,
                TapCreatedBy::class,
            ]);
    }
}

ご覧のとおり、パイプラインの使用を開始して、イベント モデリング用の複数の動作を追加できます。これはまだテストされていないので、それが可能かどうかは 100% わかりませんが、概念としては、モデル イベントに反応する構成可能な方法を開く可能性があります。

Laravel プロジェクトでモデル イベントをどのように処理しますか? Twitterで教えてください!

元のアドレス: https://laravel-news.com/working-with-laravel-model-events

翻訳アドレス: https://learnku.com/laravel/ t/71183

プログラミング関連の知識については、プログラミング ビデオをご覧ください。 !

以上がLaravelでモデルイベントを使用する方法について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。