Implementing Soft Deletes in Laravel Eloquent Models

Nov 27, 2025 · Programming · 11 views · 7.8

Keywords: Laravel | Soft Delete | Eloquent | PHP | Database

Abstract: This article provides a comprehensive guide to implementing soft deletes in Laravel using the Eloquent ORM. Soft deletes allow marking records as deleted without physically removing them from the database by setting a deleted_at timestamp. It covers implementation differences across Laravel versions, database migrations, soft delete operations, query handling, restoration, and permanent deletion, with practical examples and best practices integrated from core Eloquent concepts.

Introduction to Soft Deletes

Soft delete is a database design pattern that allows marking records as deleted without actually removing them from the database. In Laravel, this is achieved by setting a deleted_at timestamp column. When a model uses soft deletes, calling the delete method sets the deleted_at column to the current timestamp, and queries automatically exclude these records. This approach is useful for maintaining data history or implementing recycle bin features.

Enabling Soft Deletes in Laravel Models

To enable soft deletes in Laravel, specific traits must be used in the model class. For Laravel 5.0 and later, use the Illuminate\Database\Eloquent\SoftDeletes trait. Example code:

<?php

namespace App\Models;

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

class Post extends Model
{
    use SoftDeletes;

    protected $table = 'posts';
    // Other property definitions
}

For Laravel 4.2, use the SoftDeletingTrait:

<?php

use Illuminate\Database\Eloquent\SoftDeletingTrait;

class Post extends Eloquent
{
    use SoftDeletingTrait;

    protected $table = 'posts';
    // Other property definitions
}

In versions prior to 4.2, enable it by setting protected $softDelete = true;. These methods ensure the model supports soft deletes without affecting other Eloquent operations.

Database Migration Setup

To use soft deletes, a deleted_at column must be added to the database table. Laravel's migration tools provide a convenient method. In the up method of a migration file, use the softDeletes method to add this column:

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        // Other field definitions
        $table->softDeletes(); // Adds the deleted_at column
        $table->timestamps();
    });
}

This creates a deleted_at column of timestamp type, defaulting to NULL. When a record is soft deleted, this column is set to the current timestamp.

Performing Soft Deletes and Restoration

Once soft deletes are enabled, standard Eloquent methods can be used. Calling the delete method performs a soft delete:

$post = Post::find($id);
$post->delete(); // Sets deleted_at to the current timestamp

To restore a soft deleted record, use the restore method:

$post->restore(); // Sets deleted_at to NULL

For permanent deletion, use the forceDelete method:

$post->forceDelete(); // Permanently removes the record from the database

These operations can be integrated with Eloquent's event system, such as triggering custom logic on deletion or restoration.

Querying Soft Deleted Records

By default, Eloquent queries automatically exclude soft deleted records. To include them, use the withTrashed method:

$posts = Post::withTrashed()->get(); // Retrieves all records, including soft deleted ones

To retrieve only soft deleted records, use the onlyTrashed method:

$deletedPosts = Post::onlyTrashed()->get(); // Retrieves only soft deleted records

These methods allow flexible data handling, such as displaying deleted items in an admin interface.

Advanced Topics and Best Practices

Soft delete functionality integrates closely with other Eloquent features. For example, global scopes can customize query behavior, and event listeners can execute additional actions on soft delete. According to Laravel documentation, soft deleted models trigger events like deleted and restored, which can be used for logging or notifications. Additionally, ensure the use of fillable or guarded properties in models to prevent mass assignment vulnerabilities. For performance with large datasets, consider using chunked queries to avoid memory issues.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.