IMHO, the current Database channel for saving notifications in Laravel is really bad design:
- You can't use foreign key cascades on items for cleaning up notifications of a deleted item for example
- Searching custom attributes in the
data
column (casted to Array) is not optimal
How would you go about extending the DatabaseNotification
Model in vendor package?
I would like to add columns event_id
, question_id
, user_id
(the user that created the notification) etc... to the default laravel notifications
table
How do you override the send
function to include more columns?
In:
vendor/laravel/framework/src/Illuminate/Notifications/Channels/DatabaseChannel.php
The code:
class DatabaseChannel
{
/**
* Send the given notification.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return \Illuminate\Database\Eloquent\Model
*/
public function send($notifiable, Notification $notification)
{
return $notifiable->routeNotificationFor('database')->create([
'id' => $notification->id,
'type' => get_class($notification),
\\I want to add these
'user_id' => \Auth::user()->id,
'event_id' => $notification->type =='event' ? $notification->id : null,
'question_id' => $notification->type =='question' ? $notification->id : null,
\\End adding new columns
'data' => $this->getData($notifiable, $notification),
'read_at' => null,
]);
}
}
An example for @cweiske response.
If you really need extends the
Illuminate\Notifications\Channels\DatabaseChannel
not creating a new Channel you can:Extends the channel:
And register the
Illuminate\Notifications\Channels\DatabaseChannel
on application container again:app\Providers\AppServiceProvider.php
Now when the
Illuminate\Notifications\ChannelManager
trycreateDatabaseDriver
will return your registered database driver.More one option to solve this problem!
I solved a similar problem by customizing notification class:
create the class for this action:
inside it:
then you can access proper data in view or controller like this:
Create and use your own
Notification
model andNotifiable
trait and then use your own Notifiable trait in your (User) models.App\Notifiable.php:
App\Notification.php:
App\User.php:
Unlike "Bassem El Hachem", I wanted to keep the
database
keyword in thevia()
methods.So in addition to a custom
DatabaseChannel
, I also wrote my ownChannelManager
that returns my ownDatabaseChannel
in thecreateDatabaseDriver()
method.In my apps'
ServiceProvider::register()
method, I overwrote the singleton for the original ChannelManager class to return my custom manager.To create a custom Notification Channel:
First, create a Class in App\Notifications for example:
Second, use this channel in the
via
method in the Notification class: