Trong Laravel, Soft Delete là một tính năng giúp xóa bản ghi mà không thực sự xóa nó khỏi cơ sở dữ liệu. Chức năng này đã được Laravel hỗ trợ từ phiên bản 5.0, giúp lập trình viên dễ dàng quản lý dữ liệu mà không cần tạo hệ thống lưu trữ phức tạp. Thay vì xóa hoàn toàn, Laravel chỉ đánh dấu bản ghi là "đã xóa" bằng cách thêm giá trị vào cột deleted_at. Điều này giúp bạn khôi phục lại dữ liệu khi cần thiết. Trong bài viết này, codetuthub.com sẽ hướng dẫn bạn cách sử dụng Soft Delete trong Laravel một cách hiệu quả.
Bài viết này có sử dụng lại source code của bài viết Hướng dẫn lưu trữ dữ liệu JSON trong Laravel 11 một cách hiệu quả để demo. Nếu bạn chưa có sẵn project Laravel vui lòng tham khảo các bước để cài đặt.
1. Cấu hình Soft Delete trong Model
Laravel hỗ trợ Soft Delete thông qua trait SoftDeletes. Để sử dụng, hãy làm theo các bước sau.
1.1. Tạo migration với bảng chứa cột deleted_at
Trước tiên, bạn cần tạo một bảng mới có cột deleted_at trong cơ sở dữ liệu. Nếu bạn chưa có migration, hãy tạo bằng lệnh sau:
php artisan make:migration create_posts_tableMở file migration mới được tạo trong thư mục database/migrations/, sau đó chỉnh sửa như sau thêm cột deleted_at vào phương thức up():
<?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::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->softDeletes(); // Thêm cột deleted_at
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('posts');
}
};
Chạy migration để áp dụng thay đổi:
php artisan migrateSau khi chạy migration, bảng post đã được tạo và có cột deleted_at:

1.2. Kích hoạt Soft Delete trong Model
Tạo model Post để làm việc với dữ liệu:
php artisan make:model PostMở file app/Models/Post.php chỉnh sửa và thêm trait SoftDeletes vào model:
Bây giờ, Laravel sẽ tự động xử lý Soft Delete khi bạn xóa một bản ghi.
2. Sử dụng Soft Delete trong Laravel
2.1. Xóa bản ghi bằng Soft Delete
Thay vì sử dụng delete(), bạn chỉ cần gọi:
$post = Post::find(1);
$post->delete();Bản ghi sẽ không bị xóa khỏi cơ sở dữ liệu mà chỉ cập nhật deleted_at với thời gian hiện tại.
2.2. Lấy danh sách bản ghi chưa bị xóa
Khi sử dụng Post::all(), Laravel sẽ tự động lọc các bản ghi đã bị Soft Delete. Bạn có thể lấy danh sách các bản ghi chưa bị xóa như sau:
$posts = Post::all();2.3. Lấy cả các bản ghi đã bị xóa
Để lấy tất cả bản ghi, bao gồm cả những bản ghi đã bị xóa:
$posts = Post::withTrashed()->get();2.4. Chỉ lấy các bản ghi đã bị xóa
Bạn có thể lấy các bản ghi đã bị Soft Delete bằng cách:
$deletedPosts = Post::onlyTrashed()->get();2.5. Khôi phục bản ghi đã xóa
Nếu bạn muốn khôi phục một bản ghi đã bị Soft Delete, hãy sử dụng restore():
$post = Post::withTrashed()->find(1);
$post->restore();Bản ghi sẽ quay trở lại danh sách các bản ghi hoạt động.
2.6. Xóa vĩnh viễn bản ghi
Nếu bạn muốn xóa hoàn toàn một bản ghi, hãy sử dụng forceDelete():
$post = Post::withTrashed()->find(1);
$post->forceDelete();Bản ghi này sẽ bị xóa vĩnh viễn khỏi cơ sở dữ liệu.
3. Áp dụng Soft Delete trong Controller
Tạo PosttController:
php artisan make:controller PosttControllerGiả sử bạn đang làm việc với PostController, bạn có thể cập nhật các phương thức như sau:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function show($id)
{
$post = Post::findOrFail($id);
return response()->json($post);
}
public function destroy($id)
{
$post = Post::findOrFail($id);
$post->delete();
return response()->json(['message' => 'Bài viết đã được xóa mềm!']);
}
public function restore($id)
{
$post = Post::withTrashed()->findOrFail($id);
$post->restore();
return response()->json(['message' => 'Bài viết đã được khôi phục!']);
}
public function forceDelete($id)
{
$post = Post::withTrashed()->findOrFail($id);
$post->forceDelete();
return response()->json(['message' => 'Bài viết đã bị xóa vĩnh viễn!']);
}
}
4. Tạo routes API hỗ trợ Soft Delete
Mở file routes/api.php và thêm các tuyến đường cho Soft Delete:
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Route::post('/products', [\App\Http\Controllers\ProductController::class, 'store']);
Route::get('/products/{id}', [\App\Http\Controllers\ProductController::class, 'show']);
// Add Soft Delete test
Route::get('/posts/{id}', [\App\Http\Controllers\PostController::class, 'show']);
Route::delete('/posts/{id}', [\App\Http\Controllers\PostController::class, 'destroy']);
Route::patch('/posts/{id}/restore', [\App\Http\Controllers\PostController::class, 'restore']);
Route::delete('/posts/{id}/force-delete', [\App\Http\Controllers\PostController::class, 'forceDelete']);
Bây giờ bạn có thể sử dụng Postman hoặc cURL để kiểm tra các API này.
5. Test
- Thêm một số records vào bảng post:

- Sử dụng postman để chạy các requests sau và kiểm tra kết quả ở bảng
post:
GET http://127.0.0.1:8000/api/posts/1 => Lấy thông tin post có id = 1

DELETE http://127.0.0.1:8000/api/posts/1 => Xóa mềm post có id = 1, cột deleted_at đã được cập nhật thời gian hiện tại.

PATCH http://127.0.0.1:8000/api/posts/1/restore => Khôi phục trạng thái ban đầu cho post có id = 1

DELETE http://127.0.0.1:8000/api/posts/1/force-delete => Xóa vĩnh viễn post có id = 1 ra khỏi cơ sở dữ liệu

5. Kết luận
Soft Delete trong Laravel giúp bạn bảo vệ dữ liệu quan trọng khỏi bị mất hoàn toàn, đồng thời vẫn cung cấp cách xóa và khôi phục linh hoạt. Bằng cách sử dụng SoftDeletes, bạn có thể quản lý dữ liệu hiệu quả hơn mà không cần lo lắng về việc mất dữ liệu do xóa nhầm.
Source code: https://github.com/vantoantg/laravel-11-demo/tree/soft-delete
Hy vọng hướng dẫn này từ codetuthub.com sẽ giúp bạn làm chủ tính năng Soft Delete trong Laravel. Nếu bạn có bất kỳ câu hỏi nào, hãy để lại bình luận bên dưới!









