How to Restore Soft Deleted Models in Eloquent

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

Introduction

Eloquent, the ORM (Object-Relational Mapper) included with Laravel, provides the rich functionality of handling interactions with database tables effortlessly. One powerful feature is ‘Soft Deletes’, allowing developers to ‘delete’ records from the application perspective while keeping them in the database. But what happens when you need to restore soft-deleted models? In this tutorial, we’ll explore exactly how to achieve that.

Soft Deleting

Before we dive deep into restoring soft-deleted models, let’s understand what soft deleting means in Eloquent. Soft deletes are a way to keep records in the database and simply flag them as ‘deleted’. This is achieved by assigning a timestamp to a designated ‘deleted_at’ column in your table. When Eloquent queries the models, any model with a non-null ‘deleted_at’ field is automatically excluded from query results.

Setting Up Soft Deletes

To use soft deletes in your Eloquent model, you must first ensure that the migration for your table contains the soft delete column like this:

<?php 
table->softDeletes(); 
?>

Next, to enable soft deletes in a model, you use the ‘Illuminate\Database\Eloquent\SoftDeletes‘ trait:

namespace App\Models;

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

class Post extends Model
{
    use SoftDeletes;
}

With your table prepared and your model set up, Eloquent will now handle soft deletes automatically. When you call the delete() method on the model, Eloquent will set the ‘deleted_at’ timestamp instead of truly deleting the record.

Restoring Soft Deleted Models

To restore soft-deleted records, Eloquent provides the restore() method. To call this method on a model instance, you first need to retrieve soft deleted models. Here’s how to do it:

use App\Models\Post;

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

foreach ($trashed as $post) {
    $post->restore();
}

In the code sample above, onlyTrashed() is a method that modifies the query to fetch only the models that have been soft deleted. Next, use a foreach loop to iterate over the collection and restore each one.

Often, you might need to perform a restore operation on a known ID or set of IDs, you can use:

// Restore a single post with id 1
Post::withTrashed()->where('id', 1)->restore();

// Restore multiple posts with ids 1, 2, and 3
Post::withTrashed()->whereIn('id', [1, 2, 3])->restore();

The withTrashed() method returns both soft-deleted and non-deleted models, allowing you to perform operations irrespective of their deleted status.

Restoring Related Soft Deleted Models

There are situations where you have related models that also use soft deletes. If you want to restore a parent model and all its related child models, there’s a bit more work to do. Let’s see an example with a one-to-many relationship:

use App\Models\User;

$user = User::withTrashed()->findOrFail($userId);
$user->restore();

foreach ($user->posts as $post) {
    $post->restore();
}

Note that the posts() method would normally return only the non-deleted posts. To include soft-deleted posts in the loop, you must explicitly ask for them: foreach ($user->posts()->withTrashed()->get() as $post) { $post->restore(); }

Events and Observers

Like other Eloquent operations, restoring soft deleted models fires model events. The restoring and restored events allow you to hook into the operations before and after they happen:

Post::restoring(function ($post) {
    // Called before a soft-deleted model is restored
});

Post::restored(function ($post) {
    // Called after a soft-deleted model is restored
});

If you use model observers, the same events can be handled in the observer class:

class PostObserver
{
    public function restoring(Post $post)
    {
        // Logic before restoring
    }

    public function restored(Post $post)
    {
        // Logic after restoring
    }
}

// Register the observer in an appropriate service provider:
Post::observe(PostObserver::class);

Using observers is especially useful when there’s a substantial amount of logic to be executed during the restore operation.

Conclusion

In this guide, we’ve covered how to restore soft deleted Eloquent models. With this knowledge, you can handle scenarios where you need to ‘undo’ a delete operation or manage trashable content with ease. Eloquent’s native soft delete functionality coupled with restore methods provides a robust solution for managing deletions in Laravel applications.