Laravel 9 All About Model Observers

Hello Artisans, today I'll talk about Laravel Model observers. How do observers work or how we can use them? Laravel model observers are used to group event listeners for a model eloquent. Observer methods are fired when any type of event is dispatched through our eloquent model. The events are create(), update() or delete(). The observer methods are:

  • Retrieved: After a record has been retrieved.
  • Creating: Before a record has been created.
  • Created: After a record has been created.
  • Updating: Before a record is updated.
  • Updated: After a record has been updated.
  • Saving: Before a record is saved (either created or updated).
  • Saved: After a record has been saved (either created or updated).
  • Deleting: Before a record is deleted or soft-deleted.
  • Deleted: After a record has been deleted or soft-deleted.
  • Restoring: Before a soft-deleted record is going to be restored.
  • Restored: After a soft-deleted record has been restored

So, let's see an example of how observers works.

Example

We'll see a simple example where by creating a post. Where in our posts table has a column of name,slug and unique_id. In the controller we'll save only the name of a posts. But our observer will help us to create the slug and unique_id of a post.

Note: Tested on Laravel 9.2.

Table of Contents

  1. Setup Migration and Model
  2. Create and Setup Observer
  3. Create and Setup Controller
  4. Define Routes

Setup Migration and Model

At first create a model and migration file using the below command

php artisan make:model Post -m

It'll create a Post.php under app\Models and a posts migration file under database/migrations.

Now open the posts migration file put the below code

database/migrations/2022_04_29_120847_create_posts_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('slug');
            $table->string('unique_id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
};

Now migrate the table using the below command.

php artisan migrate

Now open the Post.php and and replace yours with the below code

app/Models/Post.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;
    
    protected $fillable = ['name','slug','unique_id'];
}

Create and Setup Observer

To create a observer, fire the below command in your terminal

php artisan make:observer PostObserver --model=Post

It'll create a file called PostObserver.php under app/Observers. We'll use the creating() and created() method as of our example. So, put the below code in yours observer.

app/Observers/PostObserver.php
<?php

namespace App\Observers;

use App\Models\Post;
use Illuminate\Support\Str;

class PostObserver
{
    public function creating(Post $post)
    {
        $post->slug = Str::slug($post->name);
    }

    public function created(Post $post)
    {
        $post->unique_id = 'PR-'.$post->id;
        $post->save();
    }

    public function updated(Post $post)
    {
        //
    }

    public function deleted(Post $post)
    {
        //
    }

    public function restored(Post $post)
    {
        //
    }

    public function forceDeleted(Post $post)
    {
        //
    }
}

Now we've to register the Observer in EventServiceProvider boot() as below

app/Providers/EventServiceProvider.php
<?php

namespace App\Providers;

use App\Models\Post;
use App\Observers\PostObserver;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array<class-string, array<int, class-string>>
     */
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
    ];

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        Post::observe(PostObserver::class);
    }

    /**
     * Determine if events and listeners should be automatically discovered.
     *
     * @return bool
     */
    public function shouldDiscoverEvents()
    {
        return false;
    }
}

Create and Setup Controller

Now we'll create a controller where we'll write our logic we'll save only name of a post and rest of the work done by observer that we'll register on #step2. So, fire the below command in the terminal to create a controller.

php artisan make:controller PostController

It'll create a controller under app\Http\Controller\PostController.php. Open the file and put the below codes.

app/Http/Controllers/PostController.php
<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function store()
    {
        $post = Post::create([
            'name' => 'Laravel Observer',
        ]);

        dd($post);
    }
}

Define Routes

Put the below routes in your web.php.

routes/web.php
Route::get('post', [\App\Http\Controllers\PostController::class, 'store']);

That's it for today. Hope you've enjoyed this tutorial. You can also download this tutorial from GitHub. Thanks for reading.