Laravel

Eloquent ORM Soft Delete & Permanent Delete in Laravel

January 30, 2018

author:

Eloquent ORM Soft Delete & Permanent Delete in Laravel

We can perform delete operation in Laravel in two ways. Either remove a record from database permanently or delete but keep the record hanging in the database. Confused? Let us start with discussing the permanent delete operation.

# Delete

This is the basic database delete operation. On deleting, the record is removed from the database table. For deleting, a delete() method on the model instance is called:

# Controller

use App\Post;
...
public function destroy($id)
{
    //delete with primary key
    $post = Post::find(1);
    $post->delete();

    //delete with key (primary key)
    Post::destroy(1);

    //delete specific rows
    $deletedRows = Post::where('comments', 0)->delete();
}

# Soft Deletes

While actually removing the records from database tables, Laravel has a feature to soft delete the models. When models are soft deleted, they aren’t removed from the database. Instead, a deleted_at flag is set on the model and inserted into the database. Now, to check whether a model is deleted or not, we can check deleted_at value. If it is non-null, it can be concluded that the model has been soft deleted.

Laravel how to Soft Delete?

To enable this feature, we need to use Illuminate\Database\Eloquent\SoftDeletes trait on the model. We also need to add an extra column named deleted_at to the $dates property of the model.

# app/Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
   use SoftDeletes;

   protected $dates = ['deleted_at'];
}

In addition, we need to add a deleted_at column in our database (or migration) for mapping purpose.

Schema::create('blogs', function (Blueprint $table) {
    ...
    $table->softDeletes();
});

We can now call delete() method as before. However, as we call this method now, the deleted_at column will be set to current date-time. And if we query the same model that uses soft deletes, the soft deleted models will be automatically excluded from all the database query results. However, we can determine if a certain model has been soft deleted with the eloquent trashed method:

if ($post->trashed()) {
  //some logic
}

# Soft Deleted Models Query Operations

As we discussed, soft deleted models are excluded from query results. But we can forcefully include soft deleted models in query results using eloquent’s withTrashed() method on the query. Here some operations that can be helpful:

# Include Soft Deleted Models

$posts = Post::withTrashed()->get();

# Retrieve only Soft Deleted Models

For such cases, onlyTrashed() method is used:

$posts = Post::onlyTrashed()->get();

# Restore Soft Deleted Models

To bring back such models to un-deleted state, restore() method can be used:

Restore all models:

Post::restore();

Restore specific models:

Post::withTrashed()
    ->where('comments', 100)
    ->restore();

# Permanently Deleting Models

You may now ask how do I permanently delete a soft deleted item? There are instances when we would actually want to permanently remove the soft deleted models. In such case, we can use:

$post->forceDelete();

Parting Thoughts
Since soft delete is a new feature as a learning curve, we tried to have a deep and clear look at it. We also saw several use cases and how it can be really helpful. You can always come back to the sections that aren’t clear to you.

Leave a comment

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