Explore soft deletes in Eloquent: A developer’s guide

Updated: January 16, 2024 By: Guest Contributor Post a comment

Introduction

Soft deletes are a critical feature when it comes to managing deletion of records in web applications. Instead of permanently removing an entry from the database, a soft delete marks a record as ‘deleted’ without actually removing it. This allows for recovery of records at a later point if necessary. Laravel’s Eloquent ORM supports soft deletes out of the box, providing developers a convenient and efficient way to handle such scenarios. This tutorial explores the implementation and use of soft deletes in Eloquent.

Enabling Soft Deletes

Soft deleting functionality is enabled by including the SoftDeletes trait in your Eloquent model. Doing so adds a deleted_at column to your table schema which indicates if a row is soft deleted.

<?php

namespace App;

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

class Post extends Model
{
    use SoftDeletes;
}

You’ll also need to add the deleted_at column to your database table, which can be done via a migration:

<?php

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

class AddSoftDeletesToPosts extends Migration
{
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->softDeletes();
        });
    }

    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropSoftDeletes();
        });
    }
}

Using Soft Deletes

Once soft deletes have been set up, deleting a model is done using the same delete() method as for a hard delete:

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

This won’t remove the record from the database but will fill the deleted_at column with the current timestamp. The Eloquent query builder will automatically exclude soft deleted models from the query results:

$posts = Post::all();

The above query will only return posts that are not soft deleted.

Retrieving Soft Deleted Models

To include soft deleted models in a result set, use the withTrashed() method:

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

If you need to retrieve only the soft deleted models, you can use the onlyTrashed() method:

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

Restoring Soft Deleted Models

Soft deleted models can be restored using the restore() method:

$post->restore();

The restore() method clears the deleted_at column, bringing the soft deleted model back into the normal dataset.

Permanently Deleting Models

To permanently delete a soft deleted model, use the forceDelete() method:

$post->forceDelete();

Querying Relations with Soft Deletes

Soft delete functionality is also available when querying relations. To include related models with soft deletes, use the withTrashed():

$comments = $post->comments()->withTrashed()->get();

To get only the deleted relations, append the onlyTrashed() method:

$deletedComments = $post->comments()->onlyTrashed()->get();

Advanced Usage: Customizing The Deleted At Column

Eloquent allows you to customize the name of the deleted_at column used by the SoftDeletes trait. You can achieve this by overriding the DELETED_AT constant in your model:

<?php

namespace App;

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

class Post extends Model
{
    use SoftDeletes;

    const DELETED_AT = 'archive_at';
}

Conclusion

Soft deletes in Eloquent provide a robust solution for managing record deletion while maintaining the integrity of data. They offer an essential set of functionalities for building resilient web applications that handle data revisions and recoveries gracefully.