Laravel Soft Delete and Restore Example

Laravel provides a built-in feature to flag database rows as deleted without deleting them from the database. In this article, we will see how soft delete and restore works in Laravel.

Why Use Soft Delete?

Sometimes we need to delete some data from the database but we will need those data again when required or temporarily block those data from being used then soft delete comes into the limelight. Restoring data is too painful to process when working with live databases so soft delete can be handy for restoring data.

When a user deletes some data accidentally then it will be messy to restore that data but with soft delete, we can achieve it easily.

In this example, we will create a Model for Post and perform a Soft delete and restore on it. In Addition, we will see force delete too. So let’s create a model for testing

Post Model and Migration

First of all, let’s create a Post Model and migration. you will use Soft delete in this model.

Soft delete uses Laravel Illuminate\Database\Eloquent\SoftDeletes trait. So you need to import it into our application. Also, you need to add a use statement to use this trait in your application.

php artisan make:model Post -m

It will create a model and migration file for posts. Let’s modify it one by one:

<?php

namespace App\Models;

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

class Post extends Model
{
    use HasFactory, SoftDeletes;

    public $fillable = [
        'title',
        'content',
        'category',
    ];

    protected $dates = ['deleted_at'];
}

In this model, you just need to make a few changes so it can work with soft delete. First of all, import the SoftDeletes trait and use it in your model. Then you just add the required fields into fillable and type cast deleted_at.

Now your model is ready to use soft delete and restore. There is one more thing to add the deleted_at column into your database table. Make changes to your post-migration file and add the delete_at column using softDeletes() function.

<?php

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

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->string('category');
            $table->softDeletes();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Now your Post model is ready to use soft delete and restore functionality. You can use the model normally to get data. like the below example :

//Get Post By ID
$post = Post::find(1);

//Get all posts
$posts = Post::all();

//Get post by category
$category_posts = Post::where('category',$category)->get()->json();

Delete Model using Soft Delete

Soft delete doesn’t affect any other methods. But when you use the delete method then it will update the delete_at column for that record. like the below example :

$post = Post::find(1)->detete();

It will update the deleted_at column of that row and when you try to fetch data again it will skip those records where delete_at is not NULL,

Get soft-deleted records

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

This query will return all deleted records. You can restore those records as per your requirement.

Restoring Deleted records

You can restore deleted records as per your requirements. To restore deleted records you need to use the restore() method in Laravel.

//Restore all Deleted Posts
$deleted_posts = Post::withTrashed()->get()->restore();

//Restore specific with pecific condition
$data = Post::withTrashed()->where('category',$category)->first()->restore();

Permanently Deleting Models

Sometimes you want to delete data permanently from our database. you can achieve those using the forceDelete() method.

Post::find(1)->forceDelete();

You may also use the forceDelete() method when building Eloquent relationship queries:

Post::find(1)->history()->forceDelete();