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:
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:
<?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
- Soft Deleting (Laravel Documentation)