Back to Course |
Laravel User Timezones Project: Convert, Display, Send Notifications

Scheduled Notifications in DB: The Model

In this step, we'll build the Model that will store our scheduled notifications:


Creating the Migration

Let's start by creating the migration for our Model:

php artisan make:migration create_scheduled_notifications_table

Migration

public function up(): void
{
Schema::create('scheduled_notifications', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('notification_class');
$table->morphs('notifiable');
$table->boolean('sent')->default(0);
$table->boolean('processing')->default(0);
$table->dateTime('scheduled_at');
$table->dateTime('sent_at')->nullable();
$table->integer('tries')->default(0);
$table->timestamps();
});
}

These fields include:

  • user_id - the user that the notification is for
  • notification_class - the class of the notification that will be sent
  • notifiable - the Model that is associated with the notification
  • sent - whether the notification has been sent
  • processing - whether the notification is currently being processed (for example, if a Job runs too long, we don't want to re-send)
  • scheduled_at - the date and time when the notification should be sent (in UTC time that matches Users timezone)
  • sent_at - the date and time when the notification was sent (Great for backlog and debugging!)
  • tries - the number of times the notification has been attempted to be sent (we'll limit it to 5 attempts)

Creating the Model

Next, we'll create the Model that will be used to interact with the database:

app/Models/ScheduledNotification.php

 
use App\Jobs\ProcessNotificationJob;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
 
class ScheduledNotification extends Model
{
protected $fillable = [
'user_id',
'notification_class',
'notifiable_id',
'notifiable_type',
'sent',
'processing',
'scheduled_at',
'sent_at',
'tries',
];
 
protected $casts = [
'sent' => 'boolean',
'processing' => 'boolean',
];
 
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
 
public function notifiable(): MorphTo
{
return $this->morphTo();
}
}

Last, we need some relationships to access all the scheduled notifications from the User and Booking Models.


Adding Relationship to User and Booking Models

To allow us to check if a user or a booking has scheduled notifications - we should add a relationship to the Models:

app/Models/User.php

// ...
 
public function scheduledNotifications(): HasMany
{
return $this->hasMany(ScheduledNotification::class);
}
 
// ...

app/Models/Booking.php

// ...
 
public function scheduledNotifications(): MorphMany
{
return $this->morphMany(ScheduledNotification::class, 'notifiable');
}
 
// ...

This way we will have the ability to list all upcoming/past notifications for our user or booking by just calling the $user->scheduledNotifications or $booking->scheduledNotifications relationship.