Laravel provides an elegant way to handle model events using the Observer pattern. In this guide, we will walk through implementing job notifications using an Observer, ensuring that users subscribed to a job category receive an email notification when a new job is posted.
Observers allow us to automatically execute logic when a model event occurs, keeping our controllers and models clean. By using an Observer, we can listen for job creation events and trigger notifications without adding additional logic inside the controller.
Run the following command to generate an observer:
php artisan make:observer JobObserver --model=Job
This command will create a new observer file at:
app/Observers/JobObserver.php
Open app/Observers/JobObserver.php
and modify it as follows:
namespace App\Observers;
use App\Models\Job;
use App\Models\Subscription;
use App\Notifications\NewJobNotification;
use Illuminate\Support\Facades\Notification;
class JobObserver
{
public function created(Job $job)
{
// Get all users subscribed to this job category
$subscribers = Subscription::where('category_id', $job->category_id)->pluck('user_id');
// Send notification
Notification::send(
User::whereIn('id', $subscribers)->get(),
new NewJobNotification($job)
);
}
}
Open app/Providers/AppServiceProvider.php
and update the boot
method:
use App\Models\Job;
use App\Observers\JobObserver;
public function boot()
{
Job::observe(JobObserver::class);
}
Generate the notification using:
php artisan make:notification NewJobNotification
Modify app/Notifications/NewJobNotification.php
:
namespace App\Notifications;
use App\Models\Job;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class NewJobNotification extends Notification
{
use Queueable;
protected $job;
public function __construct(Job $job)
{
$this->job = $job;
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new MailMessage)
->subject('New Job in Your Subscribed Category')
->greeting("Hello {$notifiable->name},")
->line("A new job '{$this->job->title}' has been posted.")
->action('View Job', url("/jobs/{$this->job->id}"))
->line('Thank you for using our job portal!');
}
}
We need a Subscription model and migration.
Create the subscriptions
table:
Schema::create('subscriptions', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->foreignId('category_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
app/Models/Subscription.php
)namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Subscription extends Model
{
use HasFactory;
protected $fillable = ['user_id', 'category_id'];
public function user()
{
return $this->belongsTo(User::class);
}
public function category()
{
return $this->belongsTo(Category::class);
}
}
Ensure the User
model has the Notifiable
trait:
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
}
Create a controller to handle subscriptions.
SubscriptionController.php
namespace App\Http\Controllers;
use App\Models\Subscription;
use Illuminate\Http\Request;
class SubscriptionController extends Controller
{
public function subscribe(Request $request)
{
$request->validate([
'category_id' => 'required|exists:categories,id'
]);
Subscription::firstOrCreate([
'user_id' => auth()->id(),
'category_id' => $request->category_id
]);
return back()->with('success', 'Subscribed successfully!');
}
public function unsubscribe($categoryId)
{
Subscription::where('user_id', auth()->id())
->where('category_id', $categoryId)
->delete();
return back()->with('success', 'Unsubscribed successfully!');
}
}
routes/web.php
)Route::middleware(['auth'])->group(function () {
Route::post('/subscribe', [SubscriptionController::class, 'subscribe'])->name('subscribe');
Route::delete('/unsubscribe/{category}', [SubscriptionController::class, 'unsubscribe'])->name('unsubscribe');
});
Job::create([
'title' => 'Senior Laravel Developer',
'category_id' => 1, // Ensure this category has subscribers
'company_id' => 2,
'description' => 'Job details here...',
]);
✅ Observer listens to job creation. ✅ Notification is triggered for subscribed users. ✅ Emails are sent via Laravel’s built-in notification system.
Using Laravel’s Observer pattern, you can automate notifications, making your application efficient and scalable. 🚀
Subscribe to get the latest posts sent to your email.