Bảng Pivot trong Laravel

Tram Ho

1. Giới thiệu

Nếu bạn là người mới bắt đầu với Laravel, bạn có thể không biết đến khái niệm bảng pivot và công dụng tuyệt với của nó trong các ứng dụng. Ban đầu có thể bạn sẽ thấy nó khá lạ nhưng khi sử dụng lại rất hữu ích cho mối quan hệ many-to-many đó 😄.

2. Table Pivot

Về cơ bản bảng pivot là bảng chung gian giữa hai bảng chính trong many-to-many relationships và để hiểu rõ hơn, trước tiên chúng ta sẽ giới thiệu qua về mối qua hện many-to-may này nhé!
Thực ra khi làm dự án bé nhỏ, ít nhất chúng ta cũng đã từng gặp và sử dụng đến mối quan hệ này rồi. Chắc không còn đúng không ạ.
Many-to-many là mối quan hệ này phức tạp hơn so với hasOne và hasMany. Mình sẽ lấy luôn VD như 1 User có thể sẽ có nhiều roles và 1 roles cũng thuộc về nhiều users, một post có nhiều tags, và một tags cũng có thể thuộc về nhiều posts, một shop có nhiều product và một product có thể thuộc về nhiều shop,…. Mình sẽ lấy VD Shop và Product làm ví dụ trong bài viết này nhé:
Trước tiên để xác định mối quan hệ này ngoài hai bảng chính shopsproducts chúng ta sẽ có thêm 1 bảng chung gian là product_shop (pivot table). Bảng này chứa 2 khóa ngoại là shop_id và product_id.

Về quy tắc đặt tên bảng trung gian trong Eloquent:

  • Tên của pivot table bao gồm tên của 2 bảng chính ở dạng số ít.
  • Ngăn cách nhau bởi dấu gạch dưới (underscore).
  • Sắp xếp theo thứ tự bảng chữ cái alphabetical (VD: product_shop, user_role,…).
  • Phải chứa ít nhất 2 column là khóa ngoại của 2 bảng chính (VD: shop_id và product_id).
    Tuy nhiên nếu bạn k thích có thể tự định nghĩa tên bảng trung gian.

Ở bài viết này mình sẽ bỏ qua bước tạo migration với 3 bảng shops, products và shop_product nhé 😄 Và tiếp theo mình sẽ đi định nghĩa các relations trong từng Model:

  • Model Shop

  • Quan hệ nhiều – nhiều được định nghĩa bằng cách gọi phương thức belongsToMany() dựa trên Eloquent class.

  • Như đề cập ở trước thì, để xác định tên bảng của bảng pivot tham gia vào relations, Eloquent sẽ jion 2 model liên quan theo thứ tự của bảng chữ cái. Tuy nhiên chúng ta cũng có thể ghi đè quy ước này nếu ta muốn, bằng việc truyền vào phương thức belongsToMany() tham số thứ 22 VD:
    return $this->belongsToMany(Product::class, 'shop_product_id');

  • Ta cũng có thể tùy biến các foreign key bằng cách thêm vào đồi số thứ 3 và thứ 4. Trong đó đối số thứ 3 là foreign key mà bạn đang xác định relationship và đối số thứ 4 là foreign key trong Model mà bạn đang join đến.

  • Nếu trong bảng pivot mà chúng ta có thêm 1 column thì đơn giản bạn chúng ta sẽ thêm hàm withPivot() sau định nghĩa các quan hệ.

  • Để lấy ra các cột của bảng trung gian chúng ta sử dụng thuộc tính pivot attribute:

  • Để xác định nghịch đảo của mối quan hệ nhiều nhiều này, ta cũng chỉ cần đặt 1 phương thức belongsToMany trên model còn lại của bạn.
  • Còn một lưu ý cũng khá quan trọng, đó là nếu bạn muốn bảng pivot của bạn tự động có created_at và updated_at timestamps, thì ta sử dụng các phương thức Timestamps vào trong định nghĩa của mối quan hệ VD:

Thực ra trong bài viết này mình muốn giới thiệu đến các bạn nhất đó chính là thao tác với cơ sở dữ liệu qua ba hàm attach, detachsync
Trước kia khi chưa biết đến 3 method này mình có làm một cách hơi tù, đó là tạo Model bảng trung gian xong foreach từng thằng một cho mỗi lần thêm, sửa, xóa 😄😄😄
Nhưng giờ biết đến e method kia bạn sẽ k cần phải mất công như vậy nữa hihi

1. attach
Method này được dùng trong các function store, mục đích chính của nó là thêm các bản ghi vào bảng trung gian á. VD bạn muốn add thêm sản phẩm vào một shop cụ thể chẳng hạn, thì bạn chỉ cần:

Đơn giản phải không ạ. ngoài ra nếu bạn muốn thêm nhiều bản ghi một lúc chúng ta có thể truyền lên 1 mảng $product_ids nhé, cũng tương tự đối với method detach cũng vậy
2. detach
Method này dùng trogn các function delete, destroy. VD Khi bạn muốn xóa đi 1 product trong một shop cụ thể. Nếu muốn xóa nhiều thì ta truyền thêm mảng các $shop_id nhé

Ngoài ra bạn muốn gỡ toàn bộ sản phẩm đó ở các shop

3. sync
Một function khác cũng hữu ích đó là update toàn bộ pivot table đó là method sync. Chúng ta hay sử dụng cho các function update. Lưu ý ở đây khi sử dụng method này nó chỉ chấp nhận mảng ID truyền lên và lưu vào pivot table. Do vậy, tất cả ID không nằm trong mảng ID đó sẽ bị xóa bỏ khỏi pivot table và trong pivot table lúc này sẽ chỉ còn lại ID nằm trong mảng truyền vào: VD shop 1 đang có các products 1,2,3,4,5. Nhưng mình muốn update nó có products 1,3,5,7,9 thì đơn giản ta chỉ cần:

Vậy là những products 2,4 sẽ đc loại bỏ khỏi pivot table

3. Kết luận

Trên đây là mình giới thiệu về pivot table trong laravel, cảm ơn mn đã đọc ạ (love)

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo