Classifying Soft and Hard Deletion in Eloquent Model Observers

Here’s a clean way to distinguish between soft & hard deletion events on your soft deletable Eloquent model. Include this trait into your Observer.

You can find the gist here

ClassifiesDeleted.php

<?php

namespace App\Observers;

use Illuminate\Database\Eloquent\Model;

trait ClassifiesDeleted
{
    /**
     * Hook into post-delete operations.
     *
     * @param Model $model
     */
    public function deleted(Model $model)
    {
        $method = $this->isSoftDeleted($model) ? 'softDeleted' : 'hardDeleted';

        // Call the appropriate method, if it exists.
        if (method_exists($this, $method)) {
            return $this->$method($model);
        }
    }

    /**
     * Determine if the model was soft deleted.
     *
     * @param Model $model
     *
     * @return bool
     */
    private function isSoftDeleted(Model $model)
    {
        return $model->isDirty($model->getDeletedAtColumn());
    }
}

This trait will inject two methods into your observer: softDeleted() and hardDeleted(). Here’s how that would look like in your observer.

UserObserver.php

<?php

namespace App\Observers;

use App\User;

class UserObserver
{
    /**
     * Hook into soft-deleted operations.
     *
     * @param User $user
     */
    protected function softDeleted(User $user)
    {
        //
    }
    
    /**
     * Hook into hard-deleted operations.
     *
     * @param User $user
     */
    protected function hardDeleted(User $user)
    {
        //
    }
}

Of course, in order for classification of the delete event to occur, your model must be soft deletable.

User.php

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Observers\UserObserver;

class User extends Model
{
    use SoftDeletes;

    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    public static function boot()
    {
        parent::boot();

        static::observe(new UserObserver);
    }
}

Leave a Reply

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