- Published on
Xoá dữ liệu của quan hệ con khi sử dụng Soft Deletes (cascade delete)
Mục lục
- Vấn đề khi xoá một model khi sử dụng Soft Deletes
- Xoá dữ liệu của các quan hệ con khi xoá một model
- Tự động xoá dữ liệu của các quan hệ con
Vấn đề khi xoá một model khi sử dụng Soft Deletes
Laravel cung cấp cho bạn một tính năng Soft deletes rất hữu ích. Cho bạn nào chưa biết thì Soft Deletes có nghĩa là bạn không thực sự xoá một dòng trong CSDL mà chỉ đánh dấu "đã xoá" bằng cách thêm một cột dữ liệu.
Ví dụ ta có trường hợp mối quan hệ như sau:
Như vậy khi bạn xoá một Author (tác giả), thì bạn cũng phải xoá tất cả các Post (bài viết) của tác giả đó. Đối với trường hợp xoá trực tiếp trên CSDL thì những dòng có khoá ngoại của author_id của nó cũng tự động xoá theo.
Xoá dữ liệu của các quan hệ con khi xoá một model
Bạn có thể thực hiện việc này một cách thủ công như sau:
class AuthorController extends Controller
{
public function delete($id)
{
$author = Author::find($id);
$author->post()->delete();
$author->delete();
}
}
Nhưng nếu bạn có nhiều hơn 1 quan hệ cần xoá, đoạn mã của bạn sẽ bắt đầu dài, chúng ta không nên lập lại một đoạn mã ở nhiều nơi như thế này.
Trong tình huống này, bạn có thể chuyển đoạn code xử lý này vào Model và override method delete()
của model Author
như sau:
class Author extends Model
{
public function delete()
{
$this->posts()->delete();
parent::delete();
}
}
Tự động xoá dữ liệu của các quan hệ con
Package dyrynda/laravel-cascade-soft-deletes cung cấp cho bạn một cách dễ dàng hơn bằng cách chỉ cần thêm trait CascadeSoftDeletes
vào Model và khai báo biến $cascadeDeletes
là mảng các quan hệ mà bạn muốn xoá cùng với nó.
Cài đặt dyrynda/laravel-cascade-soft-deletes
$ composer require dyrynda/laravel-cascade-soft-deletes
Thêm vào model Author
của bạn:
<?php
namespace App\Models;
use App\Models\Post;
use Dyrynda\Database\Support\CascadeSoftDeletes;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Author extends Model
{
use SoftDeletes, CascadeSoftDeletes;
protected $cascadeDeletes = ['posts'];
public function posts()
{
return $this->hasMany(Post::class);
}
}
Đơn giản hơn rất nhiều đúng không 😃