Add eloquent model events fired after a transaction is committed or rolled back

Overview

Laravel Transactional Model Events

Latest Version on Packagist Build Status Total Downloads

Add transactional events to your eloquent models. Will automatically detect changes in your models within a transaction and will fire events on commit or rollback. Should mimic the same functionality as transactional callbacks in Ruby on Rails.

You want to use this if you want to listen on events fired by models within a transaction and you want to be sure the transaction has completed successfully (or is rolled back).

Installation

You can install the package via composer:

composer require mvanduijker/laravel-transactional-model-events

Usage

Just add the trait TransactionalAwareEvents to your model or base model.

<?php

class MyModel extends Model
{
    use TransactionalAwareEvents;
}

The following events will become available:

  • afterCommit.created
  • afterCommit.saved
  • afterCommit.updated
  • afterCommit.deleted
  • afterCommit.restored
  • afterCommit.forceDeleted
  • afterRollback.created
  • afterRollback.saved
  • afterRollback.updated
  • afterRollback.deleted
  • afterRollback.restored
  • afterRollback.forceDeleted

You can add listeners in you EventServiceProvider the same way as normal events

<?php

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'eloquent.afterCommit.created: App\Models\Shipment' => [
        'App\Listeners\SendShipmentNotification',
    ],
];

Or you can put them in your model boot method:

<?php

class PictureFile extends Model
{
    use TransactionalAwareEvents;
    
    public static function boot()
    {
        parent::boot();
        
        static::registerModelEvent('afterCommit.deleted', function ($model) {
            if (Storage::exists($model->file)) {
                Storage::delete($model->file);            
            }
        });
    }
}

You should also be able to map them to event classes

<?php

class PictureFile extends Model
{
    use TransactionalAwareEvents;
    
    protected $dispatchesEvents = [
        'afterCommit.created' => PictureFileCreated::class,
        'afterCommit.deleted' => PictureFileDeleted::class,
    ];
}

And as icing on the cake, you can observe them with the following methods:

  • afterCommitCreated
  • afterCommitSaved
  • afterCommitUpdated
  • afterCommitDeleted
  • afterCommitRestored
  • afterCommitForceDeleted
  • afterRollbackCreated
  • afterRollbackSaved
  • afterRollbackUpdated
  • afterRollbackDeleted
  • afterRollbackRestored
  • afterRollbackForceDeleted

For example:

<?php

class PictureFileObserver
{
    public function afterCommitDeleted(PictureFile $model)
    {
        if (Storage::exists($model->file)) {
            Storage::delete($model->file);            
        }
    }
}

And register the observer in you ServiceProvider:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        PictureFile::observe(PictureFileObserver::class);
    }
}

Multiple database connections are supported, events are triggered when the transaction is committed on the configured connection of the model.

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Credits

License

The MIT License (MIT). Please see License File for more information.

You might also like...
Collection of the Laravel/Eloquent Model classes that allows you to get data directly from a Magento 2 database.

Laragento LAravel MAgento Micro services Magento 2 has legacy code based on abandoned Zend Framework 1 with really ugly ORM on top of outdated Zend_DB

Laravel Quran is static Eloquent model for Quran.

Laravel Quran بِسْمِ ٱللّٰهِ الرَّحْمٰنِ الرَّحِيْمِ Laravel Quran is static Eloquent model for Quran. The Quran has never changed and never will, bec

A package for Laravel One Time Password (OTP) generator and validation without Eloquent Model, since it done by Cache.

Laravel OTP Introduction A package for Laravel One Time Password (OTP) generator and validation without Eloquent Model, since it done by Cache. The ca

This package provides a trait that will generate a unique uuid when saving any Eloquent model.

Generate slugs when saving Eloquent models This package provides a trait that will generate a unique uuid when saving any Eloquent model. $model = new

Cast your Eloquent model attributes to Value Objects with ease.

Laravel Value Objects Cast your Eloquent model attributes to value objects with ease! Requirements This package requires PHP = 5.4. Using the latest

Eloquent model-caching made easy.
Eloquent model-caching made easy.

Model Caching for Laravel Supporting This Package This is an MIT-licensed open source project with its ongoing development made possible by the suppor

A MongoDB based Eloquent model and Query builder for Laravel (Moloquent)

Laravel MongoDB This package adds functionalities to the Eloquent model and Query builder for MongoDB, using the original Laravel API. This library ex

Generate UUID for a Laravel Eloquent model attribute

Generate a UUIDv4 for the primary key or any other attribute on an Eloquent model.

Laravel comments - This package enables to easily associate comments to any Eloquent model in your Laravel application

Laravel comments - This package enables to easily associate comments to any Eloquent model in your Laravel application

Comments
  • event gets fired twice

    event gets fired twice

    hi,

    i don´t know if i am doing something wrong. i am saving an "order" and its "order_items" inside a transaction. in the model "order" i am using this code:

    protected static function booted(): void {
            static::registerModelEvent('afterCommit.saved', static function ($order) {
                $order->notifyNow(new NewOrderCreated($order));
            });
        }
    

    i am using the construct:

    DB::transaction(function () {
        ..........
    });
    

    my problem is, that the notification (email) is sent twice. i am using laravel 7.16.1 and 2.3.1 of this package.

    am i doing something wrong ??

    btw... i don´t understand the difference between afterCommit.created and afterCommit.saved, but problems exists on both events.

    thanks for any help!

    opened by michabbb 9
  • Bind events via observer

    Bind events via observer

    Hi! Thanks for package!

    It will be very useful to bind events through the observer like this:

    Something::observe(SomethingObserver::class);
    
    
    class SomethingObserver{
    
        /**
         * @param Something $something
         */
        public function afterCommitSaved(Something $something): void {
            // something handler
        }
    
    opened by 4n70w4 7
  • Provide access to original attributes

    Provide access to original attributes

    Hi,

    Is there some smart way to somehow access the original attributes?

    At the time the (updated/saved) transactional event fires, Laravel has already calledsyncOriginal(), so getOriginal() returns the updated attributes instead of the originals.

    I could probably save the originals inside another attribute of the model class from within Laravels own updated or saved event. But maybe there is a way to access them in a simpler way/

    opened by gaaf 2
Releases(2.6.0)
Owner
Mark van Duijker
Freelance Web Developer
Mark van Duijker
Add The Events Calendar support to Sage 10.

The Events Calendar support for Sage 10 Add The Events Calendar support to Sage 10. For the time being there can only be a blade view, the default-tem

Supermundano 10 Nov 5, 2022
laravel zibal - transaction request package for zibal

laravel zibal transaction request package for zibal Getting Started To get a local copy up and running follow these simple steps. Installation You can

Abbas mkhzomi 4 Jan 10, 2022
Transaction-aware Event Dispatcher for Laravel

Transaction-aware Event Dispatcher for Laravel This Laravel package introduces Transaction-aware Event Dispatcher. It ensures the events dispatched wi

Francisco Neves 299 Nov 29, 2022
A laravel package to handle sanitize process of model data to create/update model records.

Laravel Model UUID A simple package to sanitize model data to create/update table records. Installation Require the package using composer: composer r

null 66 Sep 19, 2022
A laravel package to generate model hashid based on model id column.

Laravel Model Hashid A package to generate model hash id from the model auto increment id for laravel models Installation Require the package using co

Touhidur Rahman 13 Jan 20, 2022
A package to filter laravel model based on query params or retrieved model collection

Laravel Filterable A package to filter laravel model based on query params or retrived model collection. Installation Require/Install the package usin

Touhidur Rahman 17 Jan 20, 2022
Laravel-model-mapper - Map your model attributes to class properties with ease.

Laravel Model-Property Mapper This package provides functionality to map your model attributes to local class properties with the same names. The pack

Michael Rubel 15 Oct 29, 2022
Add settings to any Laravel model.

Laravel Property Bag Simple settings for Laravel apps. Easily give multiple resources settings Simple to add additional settings as your app grows Set

Zach Leigh 80 Aug 8, 2022
This package helps you to add user based follow system to your model.

Laravel Follow User follow unfollow system for Laravel. Related projects: Like: overtrue/laravel-like Favorite: overtrue/laravel-favorite Subscribe: o

安正超 1k Dec 31, 2022
Turn any Eloquent model into a list!

Listify Turn any Eloquent model into a list! Description Listify provides the capabilities for sorting and reordering a number of objects in a list. T

Travis Vignon 138 Nov 28, 2022