laravel-transaction-fire-event

Controlling events that occur in a transaction

MIT License

Downloads
4.8K
Stars
1
Committers
2

Laravel Event Control Library

Read this in other languages: English, 日本語.

トランザクション内で発生したイベントを制御するLaravelライブラリ

Packagist

Table of Contents

インストール

composer require technote/laravel-transaction-fire-event

使用方法

  1. イベントの発火を制御したいモデルで DelayFireEvent トレイトを使用

    <?php
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    use Technote\TransactionFireEvent\Models\DelayFireEvent;
    
    class Item extends Model
    {
        use DelayFireEvent;
    
        public static function boot()
        {
            parent::boot();
    
            self::saved(function ($model) {
                //
            });
        }
    
        // relation example
        public function tags(): BelongsToMany
        {
            return $this->belongsToMany(Tag::class);
        }
    }
    
  2. トランザクション内で使用した場合、トランザクション終了時まで saved, deleted イベントの発火が保留される

    DB::transaction(function () {
        $item = new Item();
        $item->name = 'test';
        $item->save();
        // saved イベントはまだ発火されない
    
        $item->tags()->sync([1, 2, 3]);
    }
    
    // トランザクション終了時に saved イベントが呼ばれるため
    // $model->tags()->sync で同期した tags が取得できる
    

発火を保留するイベントを変更

対象のイベントはデフォルトで saved, deleted です。 変更するには getDelayTargetEvents をオーバーライドしてください。

protected function getDelayTargetEvents(): array
{
    return [
        'created',
        'updated',
        'saved',
        'deleted',
    ];
}

動機

saved イベントで他のサービスとデータを連携する際に、以下のような実装の場合にうまく行かなかったため。

function save(Article $article, $entity) {
  $article->title = $entity->getTitle();
  // ...
  $article->save(); // saved イベント発火(まだ tags は同期されていない)
  
  $article->tags()->sync($entity->getTags());
}

function create($entity) {
  save(new Article(), $entity);
}

function update($entity) {
  save(Article::findOrFail($entity->getId()), $entity);
}

https://github.com/fntneves/laravel-transactional-events

がやりたいことに近かったが、 Model で trait を use するだけでやりたかった。

Author

GitHub (Technote) Blog