loading...

Laravel custom Pivot Model events (many-to-many relationship)

zubairmohsin33 profile image Zubair Mohsin ・2 min read

Laravel offers events like created, updated, saved and many other for regular Eloquent models. What about Pivot models?

Starting from Laravel 5.8, Pivot Model events are supported.

For a refresher on Pivot Models, refer to docs here.

Scenario

Let's take consider the example from docs about Many-to-Many relationship. User and Roles.

We are interested in following use case:

Whenever, a Role is assigned to a User, send a notification to Admin.

We can simply use attach method and then send notification right after that like below:


$user->roles()->attach($roleId);

$admin->notify(new RoleAssigned);

Wouldn't it be cool if we can refactor this notifying part to dedicated event and listener and clear up our controller method?

Dude, tell me already!

Let's define the Pivot mode, as RoleUser.

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class RoleUser extends Pivot
{
    //
}

Let's add the secret sauce, $dispatchesEvents array:

namespace App;

use App\Events\RoleAssigned;
use Illuminate\Database\Eloquent\Relations\Pivot;

class RoleUser extends Pivot
{
    protected $dispatchesEvents = [
      'created' => RoleAssigned::class
    ];
}

Be sure to register this event and its listener in EventServiceProvider.

Event and its listener can be simply defined just any other Event/Listener.

class RoleAssigned
{

    public $roleUser;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(RoleUser $roleUser)
    {
        $this->roleUser = $roleUser;
    }

}

class MessageCreatedListener implements ShouldQueue
{

   public function handle($event)
   {

      //access the Pivot model like below...

      $event->roleUser

      //send a notification here
   }

}

Extracting logic like "sending notifications" into Event/Listeners can be beneficial, as Listeners can be queued and notification can be sent in background.

Now, our controller function will be super simple:


public function store()
{
  $user->roles()->attach($roleId);

  //
}

Above line will fire the event (RoleAssigned) and its Listener will send the notification.

Peace 🙌🏼

Posted on by:

Discussion

pic
Editor guide
 

It seems you don't have to register model events in EventServiceProvider.
When I did that, my listener fired two times!

EDIT : my bad, I sat shouldDiscoverEvents() to true in EventServiceProvider.

 

What about Pivot models?
in laravel 5.7,
is this working with this version of laravel, Or Can i use regular model for pivot table.