Soft deletes are a way to retain deleted records in the database by marking them as deleted, instead of actually removing them from the database. This approach allows you to recover records at a later time if needed. Laravel makes implementing soft deletes straightforward, thanks to its built-in support for soft deleting.
Database Structure for soft deletes
To use soft deletes, your database table needs an additional column to mark the record as deleted. This column is typically named deleted_at
. If deleted_at
is NULL, the record is considered not deleted. When a record is soft deleted, Laravel sets the deleted_at
column to the current timestamp, which indicates the record is deleted.
Here's an example of a database table structure for a posts table that supports soft deletes:
CREATE TABLE posts (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL
);
Migrations for soft deletes
In Laravel, you define the deleted_at
column in your migration by using the softDeletes method:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
$table->softDeletes();
});
}
public function down()
{
Schema::dropIfExists('posts');
}
}
Using Soft Deletes
To enable soft deletes for a model, use the Illuminate\Database\Eloquent\SoftDeletes
trait in your model:
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model
{
use SoftDeletes;
// Model content
}
With soft deletes enabled, when you call the delete()
method on a model, Laravel will set the deleted_at
column for that model instead of removing the record from the database.
Querying Soft Deleted Models
Laravel automatically excludes soft deleted records from query results. To include soft deleted records in your query results, use the withTrashed()
method:
$posts = Post::withTrashed()->get();
To retrieve only the soft deleted records, use the onlyTrashed()
method:
$deletedPosts = Post::onlyTrashed()->get();
Restoring Soft Deleted Models
To restore a soft deleted model, use the restore()
method:
$post = Post::withTrashed()->find($id);
$post->restore();
Pros and Cons of Using Soft Deletes
Pros:
- Data Recovery: Soft deletes allow you to recover accidentally deleted records.
- Audit Trails: They help in maintaining an audit trail since you can see when a record was deleted.
- Relationship Integrity: They prevent cascading deletions that might otherwise occur in hard deletes, preserving related data integrity.
Cons:
- Performance: Over time, the table can grow in size due to the soft deleted records, potentially impacting performance.
- Complex Queries: Queries can become more complex because you have to consistently remember to filter out soft deleted records if they should not be included.
- Data Clutter: Without proper maintenance, your database can become cluttered with soft deleted records.
Final thoughts about Soft Deletes in Laravel
Soft deletes in Laravel provide a convenient and effective way to handle deletions in your apps. If you understand how to implement them correctly you can make your code more robust and user-friendly.
Main disadvantage of soft deleting a model are that queries are becoming more complex. If you have many-to-many relationships, or you want to traverse many layers of relationships soft deletes could be painful.