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 🙌🏼
Top comments (2)
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.