DEV Community

Cover image for Laravel 8 Database Notifications with Models using Collection Macro
Zack Webster
Zack Webster

Posted on • Edited on

Laravel 8 Database Notifications with Models using Collection Macro

Laravel comes with a built-in system for notifications. There are various channels for sending these notifications, such as - email, SMS & more. One of them is via the database wherein the notifications are stored and can be read as per your need.

Disclaimer - I'm assuming you are somewhat familiar with Laravel.

As per Laravel 8's official docs on Notifications, you can add 'data' to your notification by utilizing toDatabase() or toArray() method.

public function toDatabase($notifiable)
{
    return [
        'product_name' => $this->product->name,
        'user_name' => $this->user->name,
    ];
}
Enter fullscreen mode Exit fullscreen mode

& you can then display the notification in your views (via Controller).

<div>
    {{ $notification->data['user_name'] }} ordered {{ $notification->data['product_name'] }}
</div>
Enter fullscreen mode Exit fullscreen mode

But what if the product's name or user's name was updated? This is why you might want to store the IDs instead.

public function toDatabase($notifiable)
{
    return [
        'product_id' => $this->product->id,
        'user_id' => $this->user->id,
    ];
}
Enter fullscreen mode Exit fullscreen mode

Now, how about displaying the data in this approach? Well, you can fetch the respective product and user models in a controller like...

public function index() {
    $notifications = $user->notifications;
    foreach($notifications as $notification) {
       // populate data from models
       ...
    }
    return view('notifications', compact('notifications'));
}
Enter fullscreen mode Exit fullscreen mode

...wherein you can read the notification type and load respective models.

But should this be a concern of a controller? One of the simpler ways you can handle this is macroing on the DatabaseNotificationCollection inside of, perhaps, your AppServiceProvider like...

public function boot()
    {
        //
        DatabaseNotificationCollection::macro('addModels', function () {
            return $this->each(function ($notification) {
                // populate data from models
                ...
            });
        });
    }
Enter fullscreen mode Exit fullscreen mode

which then allows you to optionally load models for the notification collection via a controller like...

public function index() {
    $notifications = $user->notifications->addModels();
    return view('notifications', compact('notifications'));
}
Enter fullscreen mode Exit fullscreen mode

I've implemented a similar approach to Notifications for the purpose of demonstration on my GitHub repo. I have a custom convention in place. Feel free to have a look and add to.

Liked what you read? Support me here: https://www.buymeacoffee.com/zaxwebs

Top comments (2)

Collapse
 
bdelespierre profile image
Benjamin Delespierre

That's just fantastic

Collapse
 
bluesky0305 profile image
BlueSky03051993

Thank you very much !!!