I am developing a fairly simple application, where I want my users to be able to subscribe to notifications. So the system should:
Below is an example of different notifications they each user can subscribe to.
I am wondering how to do this using Laravel. My first idea was to:
notifications
JSON column on the users
table, and store it like (probably using the learnings from the Managing Mass User Settings lesson.){
"todo": {
"assigned": [
{
"email": true,
"slack": true
}
],
"mentioned": [
{
"email": true,
"slack": true
}
]
},
"project": {
"created": [
{
"email": true,
"slack": true
}
]
}
}
However, I am unsure if this is good practice. Further, I am also a unsure on how to actually send out the notifications dynamically.
For sending it out, I want to use Laravels notification system:
Notification::send($user, new TodoCreated($todo));
I am not sure if this is the best way, or if it makes more sense to use an Event/Listener setup? A
Also, can I utilize the via()
method on the Notification
class to dynamically specify the channels according to the user settings?
Any input would be greatly appreciated.
I think a many-to-many relationship would be more suited to this.
Tables:
User
- id
Notifications
- id
NotificationUser <-- pivot table
- notifcation_id
- user_id
- channel_id
Channel
- id
- name
To account for these additional fields in the pivot table, define them in the User model relationship:
class User extends Model
{
/**
* The roles that belong to the user.
*/
public function notifications()
{
return $this->belongsToMany(Notification::class)->withPivot(['channel_id']);
}
}
See: https://laravel.com/docs/8.x/eloquent-relationships#retrieving-intermediate-table-columns
This way, you can advantage of the relationship methods that Laravel (eloquent) comes with.
i.e:
aUser->notifications(); # Getting a list of a user's notifications
aUser->attach(1, ['channel' => 1]); # attaching a notification to the user
You can also take advantage of query scopes to retrieve one channel of notifications for the user etc
See: https://laravel.com/docs/8.x/eloquent#query-scopes
Then use the model/listener pattern as you had planned.