DEV Community

Cover image for Comprehensive Guide to Using Observers in Laravel
Adebowale Bello
Adebowale Bello

Posted on

Comprehensive Guide to Using Observers in Laravel

Introduction

Laravel Observers are a powerful feature that allows you to hook into the lifecycle events of your Eloquent models. By using observers, you can listen for various events that are fired by the model, such as when a model is created, updated, or deleted, and then execute specific logic in response to those events. This helps in keeping your code clean and maintaining the single responsibility principle.

Lifecycle Events

Observers can listen to the following model events:

  • retrieved
  • creating
  • created
  • updating
  • updated
  • saving
  • saved
  • deleting
  • deleted
  • restoring
  • restored

In this article, I will show a quick use case of sending user authentication credentials to a new user upon profiling. We will create a user model observer that sends an email to the new user when admin creates his profile on the system.

Creating an Observer

To create an observer, you can use the make:observer Artisan command. For example, to create an observer for the User model, you would run:

php artisan make:observer UserObserver --model=User
Enter fullscreen mode Exit fullscreen mode

This command will generate a new observer class in the app/Observers directory.

Registering an Observer

To register the observer, you need to add it to the boot method of one of your service providers, typically the AppServiceProvider. For example:

use App\Models\User;
use App\Observers\UserObserver;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    User::observe(UserObserver::class);
}
Enter fullscreen mode Exit fullscreen mode

Creating the UserCredentials notification class

Create a notification class to send the email if it doesn't already exist:

php artisan make:notification UserCredentials
Enter fullscreen mode Exit fullscreen mode

Update the UserCredentials notification:


namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class UserCredentials extends Notification
{
    use Queueable;

    protected $username;
    protected $password;

    /**
     * Create a new notification instance.
     *
     * @param string $username
     * @param string $password
     * @return void
     */
    public function __construct($username, $password)
    {
        $this->username = $username;
        $this->password = $password;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param mixed $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param mixed $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->greeting('Hello!')
                    ->line('Your account has been created.')
                    ->line('Username: ' . $this->username)
                    ->line('Password: ' . $this->password)
                    ->line('Thank you for using our application!');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param mixed $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

Enter fullscreen mode Exit fullscreen mode

Sample Observer

Here's an example of a UserObserver that listens for the created events:

namespace App\Observers;

use App\Models\User;
use App\Notifications\UserCredentials;
use Illuminate\Support\Facades\Log;

class UserObserver
{
    /**
     * Handle the User "created" event.
     *
     * @param  \App\Models\User  $user
     * @return void
     */
    public function created(User $user)
    {
        $plainPassword = $user->password;
        $user->notify(new UserCredentials($user->email, $plainPassword));

     /** Ensure the password is hashed if the create method 
      *  had saved plain text from the controller
      */

        $user->password = Hash::make($plainPassword);

    }
    // Other events can be handled similarly...
}
Enter fullscreen mode Exit fullscreen mode

Using the Observer

Once the observer is registered, it will automatically listen for the specified events on the model. For example, whenever a User model is created, the corresponding methods in the UserObserver will be executed, thereby sending the login credential to the created user.

Benefits of Using Observers

  1. Separation of Concerns: Observers help in keeping the model and business logic separate. This makes the codebase cleaner and more maintainable.

  2. Code Reusability: By using observers, you can reuse the same logic across multiple parts of your application without duplicating code.

  3. Centralized Logic: Observers allow you to centralize event-based logic in one place, making it easier to manage and update.

  4. Enhanced Readability: With observers, your models are free from additional responsibilities, making them easier to read and understand.

  5. Easy Testing: Observers can be tested independently of the models, which simplifies the testing process.

Conclusion

Laravel Observers provide a structured and efficient way to handle model events. By leveraging observers, you can keep your codebase clean, maintainable, and adhere to best practices like the single responsibility principle. They are a valuable tool in any Laravel developer's arsenal, promoting better organization and modularization of code.

Top comments (0)