Posts Learn Components Snippets Categories Tags Tools About
/

How to Automatically Delete Related Rows in Laravel

Learn how to automatically delete a model relationship in Laravel to ensure no leftover data remains when the relationship no longer exists

Created on Oct 25, 2021

2193 views

In this short snippet, you will learn how to automatically delete related records in Laravel (Eloquent Model) the easy and straightforward way.

Method 1: Define onDelete on Laravel Relationship


To define a relationship in Laravel (eg. Post belongs to a User) you can define it by providing the "user ID" to the "posts" migration schema and this is normally called the "foreign_key". With the foreign key definition, you can also add a constraint and have the "onDelete" method called to automatically delete the relationship when the current record is deleted.
<?php

// from 'posts' migration file you can add the following column.
$table->foreignId('user_id')
      ->constrained('users')
      ->onDelete('cascade');
Do note that the code above is available to the recent Laravel version only, for the older version you can write your code like below but if you do prefer to use the old way of writing then it's totally valid.
<?php

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

Schema::table('posts', function (Blueprint $table) {
    $table->unsignedBigInteger('user_id');

    $table->foreign('user_id')->references('id')->on('users');
});

Method 2: Use Modal boot Method


The 2nd method is to use the "boot" method that can be defined from within the model class itself. Within the boot method, you can call the deleting method which instructs the model to delete the child relationship records first then only delete the model instance itself.
<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    public static function boot() {
        parent::boot();

        static::deleting(function($user) {
             $user->posts()->get()->each->delete();
        });
    }

    // user has many posts
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}
Do note that the "->each" is using Laravel higher-order messages which are short-cuts for performing common actions on collections.

Method 3: Using Eloquent Event Observers


Just like method 2 you can make use of an eloquent event observer which essentially extracts the logic into an observer class. Do note that the class below is located within the AppServiceProvider class.
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        User::observe(UserObserver::class);
    }
}
Now for the UserObserver class, you can define the deleting method like below.
<?php

class UserObserver
{
    public function deleting(User $user)
    {
         $user->photos()->delete();
    }
}
Now any users that get deleted will automatically have their photos deleted first and then only the user record itself.

If you like our tutorial, do make sure to support us by being our Patreon or buy us some coffee ☕️

)