Implementing Job Notifications Using Laravel Observer

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.

Why Use an Observer for Job Notifications?

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.

Steps to Implement Job Notification with Observer

1. Create an Observer for the Job Model

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

2. Modify the JobObserver to Handle Job Creation

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)
        );
    }
}

3. Register the Observer

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);
}

4. Create the Notification 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!');
    }
}

5. Ensure Users Can Subscribe to Categories

We need a Subscription model and migration.

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();
});

Subscription Model (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);
    }
}

Add Notifiable Trait to User Model

Ensure the User model has the Notifiable trait:

use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;
}

6. Allow Users to Subscribe to Categories

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!');
    }
}

Define Routes (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');
});

7. Test the System

  1. Subscribe a user to a job category.
  2. Create a new job in that category:
Job::create([
    'title' => 'Senior Laravel Developer',
    'category_id' => 1, // Ensure this category has subscribers
    'company_id' => 2,
    'description' => 'Job details here...',
]);
  1. Check if users receive an email notification.

✅ 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. 🚀


Discover more from MountAviary

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *