Soft Deleting Parent & Child Models in Eloquent Laravel 5

Laravel is shipped with Eloquent and supported Soft Delete feature. We can read in Laravel Official Documentation:

In addition to actually removing records from your database, Eloquent can also “soft delete” models. When models are soft deleted, they are not actually removed from your database. Instead, a deleted_at attribute is set on the model and inserted into the database.

Soft Delete In Model Relationship

Soft deleting one model is super easy in Laravel. But how we attempt soft delete in model that has relationship to another model? For example:

User (has many) Posts (has many) Comments

If we had setup “cascade” onDelete() to our foreign key, when user is deleted then all posts referenced to user is also deleted. But, soft delete is not affected by “cascade” anymore so we have to define an event to delete child model if parent model is soft deleted.

In this case we have to setup soft deleting event in User model:

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Model
{
use SoftDeletes;

/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['deleted_at'];
   /**
* Override parent boot and Call deleting event
*
* @return void
*/
protected static function boot()
{
parent::boot();

static::deleting(function($users) {
foreach ($users->posts()->get() as $post) {
$post->delete();
}
});
}
   /**
* Define relationship with post model
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function posts()
{
$this->hasMany('App\Post');
}
}

This code is execute to run soft delete to post model that has relationship with user model when we attempt to soft delete user.

protected static function boot() 
{
parent::boot();

static::deleting(function($users) {
foreach ($users->posts()->get() as $post) {
$post->delete();
}
});
}

So, after soft deleting Post model we want to soft delete Comment model too right? Ok, we just need to override boot method in Post model like we did in User model.

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model
{
use SoftDeletes;

/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['deleted_at'];
   /**
* Override parent boot and Call deleting event
*
* @return void
*/
protected static function boot()
{
parent::boot();

static::deleting(function($posts) {
foreach ($posts->comments()->get() as $comment) {
$comment->delete();
}
});
}
   /**
* Define relationship with Comment model
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function comments()
{
$this->hasMany('App\Comment');
}
}

Done!

It’s easy to attempt multiple soft delete in relationship model. I’m sorry for my bad english, but I hope this trick is helpful to them that using Laravel Framework.