logo
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

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 😃

Nếu bạn thích những bài thế này?