How to Soft Delete Using Laravel Eloquent (With Example)

Soft deleting records in Laravel allows you to mark records as “deleted” instead of permanently removing them from the database. This can be incredibly useful when dealing with information that may need to be recovered in the future. Luckily Laravel ships with a built-in soft delete feature!

To use soft delete in Laravel Eloquent, add the SoftDeletes trait to your model, create a migration with the deleted_at column, and use the ->delete() method to mark records as deleted while retaining them in the database.

In the following step-by-step tutorial, you’ll learn how to add a soft delete feature to your Models. We’ll cover how to soft delete, restore records, or permanently delete records.

Step 1: Create a Model

First, let’s create a model for a “Post” with soft delete functionality. Generate a new model using Artisan:

php artisan make:model Post

In your Post model (located at app/Models/Post.php), add the use SoftDeletes trait and define the $dates property:

app/Models/Post.php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model
{
    use SoftDeletes;

    protected $casts = [
        'deleted_at' => 'datetime',
    ];

    // Your other model code here...
}

Step 2: Create the Migration

Generate a migration for the “posts” table to add the deleted_at column:

php artisan make:migration add_deleted_at_to_posts_table --table=posts

Modify the generated migration file by including $table->softDeletes() within the up() function. Additionally, add $table->dropSoftDeletes() to the down() method to make sure it can be undone artisan rollback:

database/migrations/2023_09_18_193614_add_deleted_at_to_posts_table.php
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->softDeletes();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropSoftDeletes();
        });
    }
};

Then, run the migration:

php artisan migrate

Step 3: Soft Delete Records

To soft delete a record in Laravel Eloquent we simply call the function ->delete() like when doing a normal deletion. However, since we’ve added the SoftDeletes trait to the Model code earlier, Laravel will automatically execute a soft delete, updating the deleted_at column with the current timestamp.

This allows you to perform soft deletes in your controller or wherever necessary using the following code:

public function softDeletePost($id)
{
    $post = Post::find($id);
    
    if (!$post) {
        return response()->json(['message' => 'Post not found'], 404);
    }

    $post->delete();
    
    return response()->json(['message' => 'Post soft deleted']);
}

Step 4: Showing Records

When retrieving posts using a model with the SoftDeletes trait added, Laravel will automatically only return those that were not deleted. This means the following code will return all your non-deleted posts:

public function showPosts()
{
    $posts = Post::get();
    
    return response()->json(['posts' => $posts]);
}

Step 5: Show Soft Deleted Records (Optional)

There may be cases where you need to display soft deleted records, such as a feature to show a “Recycle Bin” which provides users access to their previously deleted content.

To retrieve soft deleted records, you can use the withTrashed method:

public function showSoftDeletedPosts()
{
    $softDeletedPosts = Post::onlyTrashed()->get();
    
    return response()->json(['soft_deleted_posts' => $softDeletedPosts]);
}

Step 6: Restore Soft Deleted Records

To restore soft deleted records, you can use the restore method on the model:

public function restorePost($id)
{
    $post = Post::withTrashed()->find($id);
    
    if (!$post) {
        return response()->json(['message' => 'Post not found'], 404);
    }

    $post->restore();
    
    return response()->json(['message' => 'Post restored']);
}

Step 7: Permanently Delete Records

Sometimes, you need to permanently delete a soft deleted record. For instance, a user might have requested to have their data removed or you might simply wish to free up some space. In those cases, you can call the forceDelete() method instead of delete():

public function forceDeletePost($id)
{
    $post = Post::withTrashed()->find($id);
    
    if (!$post) {
        return response()->json(['message' => 'Post not found'], 404);
    }

    $post->forceDelete();
    
    return response()->json(['message' => 'Post permanently deleted']);
}

Conclusion

By following the steps outlined, you can easily add a soft delete feature to any Model in any Laravel application, and optionally, restore a soft deleted records when needed.

Now go ahead and add soft deletes to your own application. Happy coding!

References

Johan van den Broek

Johan is the creator of laracoding.com. As a child, he began tinkering with various programming languages, many of which have been long forgotten today. Currently, he works exclusively with PHP and Laravel, and his passion for programming remains to this day.

Leave a Reply

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

Recent Posts