Benjamin Crozat The web developer life

Laravel soft delete: the definitive guide for 2022

Benjamin Crozat Benjamin Crozat3 minutes read

Before you start reading this article, did you know 76 persons subscribed to my newsletter?

Join them and enjoy free content about the art of crafting websites!

Laravel soft delete: the definitive guide for 2022
Table of contents

What is a soft delete?

A soft delete is the action of marking a model as deleted without really deleting it from the database.

Imagine a deleted_at column in your database containing the date where your entry has been deleted.

How will you benefit from soft deletes

The main benefit of soft deletes is that you don’t loose data anymore. You will always be able to restore it.

You could also set up a scheduled task to clean up old soft deleted models given enough time passed. (Once they’re definitely deleted, you will be able to rely on your backups.)

How to set up a soft delete

Laravel requires you to take two easy steps to set up a soft delete.

First, specify that you need a column for soft deletion in your migration (I wrote a nice article about migrations). Once you run it, you’ll see a new deleted_at column in your posts table.

public function up()
{
Schema::table('posts', function (Blueprint $table) {
+ $table->softDeletes();
});
}

In the down() method, you can remove the column using the dropSoftDeletes() method.

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

Then, in your model, import the SoftDeletes trait.

namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
 
class Post extends Model
{
+ use HasFactory, SoftDeletes;
}

How to perform a soft delete

To soft delete in Laravel, you don’t have to change your habits. Use your model’s delete() method just like before. The only difference will be that Laravel will add the current date and time inside the deleted_at column.

$post->delete();

How to check if a model has been soft deleted

To check if a model has been soft deleted, use the trashed() method.

if ($post->trashed()) {
//
}

More helpers for soft deletes

Sometimes, you may need to include soft deleted models in your queries. The withTrashed() scope can help with that.

Post::withTrashed()->get();

You can even query trashed models only:

Post::onlyTrashed()->get();

Also, since the model is never really deleted, you can restore it at any moment using the restore() method. The deleted_at column will be back to NULL.

$post->restore();

Finally, if you want to really remove a soft deletable model from the database definitely, use the forceDelete() method.

$post->forceDelete();

How to test for a soft delete

To test for a soft delete in Laravel, use the assertSoftDeleted() method Laravel provides.

Here’s a basic example of how I’d go for it:

public function test_it_soft_deletes_posts()
{
$post = Post::factory()->create();
 
$this
->deleteJson(route('posts.destroy', $post))
->assertNoContent();
 
$this->assertSoftDeleted($post);
}

The inverse method exists as assertNotSoftDeleted().

How to clean up old soft deleted models

You can use the pruning mechanism Laravel offers to clean up old soft deleted models.

For example, import the Prunable trait inside your model and tell the framework to remove models that have been soft deleted since a month or more.

namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Prunable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
 
class Post extends Model
{
use HasFactory, Prunable, SoftDeletes;
 
public function prunable()
{
return static::where('deleted_at', '<=', now()->subMonth());
}
}

Don’t forget to run the model:prune command with the scheduler. Add it to your app/Console/Kernel.php:

protected function schedule(Schedule $schedule)
{
+ $schedule->command('model:prune')->daily();
}

Other posts to read

Here are the best GDPR-compliant Google Analytics alternatives to help you avoid the GDPR penalty and keep your users safe.

Knowing which Laravel version you are running is important before you start writing code on a new project. There are multiple ways to do so.

Hiring a good developer can be challenging. But if you follow these tips and you will be able to hire the right fit for your projects.

To keep getting better with PHP, you should subscribe to as many quality blogs as possible. In this article, I share the ones I often read myself.

PHP 8.3 will be released in November 2023, and as usual, you need to be up to date with new features and breaking changes for easier transitions.

Learn why and how to fix "Methods with the same name as their class will not be constructors in a future version of PHP" warnings.

Take your code to the next level, thanks to exceptions. Handle errors in a more graceful way within try and catch blocks.

Learning a framework can be overwhelming. Time and practice will make you a master. Here are some best practices to help you toward your goal.

Job interviews are not as tough as they seem. I will give you guidance through my past experiences and a list of easy questions that will make you stand out.

There are multiple ways to check if an array is empty. Let me tell you about each of them and why and when you should use them.