[Phần 1] Tìm hiểu các method hỗ trợ quan hệ nhiều nhiều (many-to-many) trong Laravel

Chào các bạn ! Khi làm việc với các relationship trong database chắc hẳn chúng ta không thể bỏ qua relationship many-to-many. Trong bài viết hôm nay tôi sẽ giới thiệu hai method hỗ trợ thao tác với quan hệ many-to-many trong Laravel 5.4 khá hay.

I.Chuẩn bị dữ liệu

1. Chúng ta có 3 table: user, role, user_role. Tương đương với đó, ta có 3 model. a. User

  • Chứa các thông tin của của user. Chẳng hạn: username, email, pasword,role_id,...
  • Model User
namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The roles that belong to the user.
     */
    public function roles()
    {
        return $this->belongsToMany('App\Role');
    }
}

b. Table role

  • Qui định các quyền hạn (role) trên hệ thống. Chẳng hạn: admin, sub-admin, super-admin,...
  • Model Role:
namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    /**
     * The users that belong to the role.
     */
    public function users()
    {
        return $this->belongsToMany('App\User');
    }
}

c. Relationship giữa user và role

  • Quan hệ giữa user và rolemany-to-many. Để thể hiện quan hệ này thì chúng ta sẽ tạo 1 table user_role.
  • Table user_role qui định quyền hạn của user trên các module trong hệ thống. Biểu diễn như sau:
user_id role_id module_name
1 1 A

II. Tìm hiểu các method hỗ trợ many-to-many

1. Method sync() a. Vai trò của method

Update lại các record ở table trung gian. Với parameters đưa vào là một Array

  • Các ID nằm trong mảng sẽ được lưu lại ở table trung gian.
  • Các ID mà không nằm trong mảng này sẽ bị xóa khỏi table trung gian nếu trước đó đã được lưu

Ví dụ

$arrayIds = [1, 2, 3];
$user->roles()->sync($arrayIds);

b. Ví dụ thực tế

  • Giả sử:

Table user_role đang lưu user A (user_id là 1) có 5 role khác nhau trên 5 module.

user_id role_id module_name
1 1 A
1 2 B
1 3 C
1 4 D
1 5 E

Table role có các quyền như sau:

id role_name
1 Admin
2 Sub-Admin
3 Super-Admin
4 Mod
5 Sub-Mod
6 Manager

Yêu cầu 2

  • Xóa hết các quyền hiện tại của User A trên hệ thống. Đồng thời, chỉ thêm 1 quyền mới cho user A trên Module H với quyền là Admin
  • Với yêu cầu ta có thể xem xét dùng method sync() để optimize code. Mình trình bày như sau:
$user->role([ 1 => ['module_name' => 'H']]);

Giai thích:

  • Với yêu cầu này chúng ta chỉ cần đưa vào 1 array dạng: related_id => ['field' => 'giá trị']

Với một dòng lệnh này thì chúng ta có thể xử lí được yêu cầu phức tạp như trên phải không nào 😃

2. Method syncWithoutDetaching() a. Vai trò

  • Nếu như method sync() sẽ xóa các ID không nằm trong Array truyền vào ở table trung gian thì method syncWithoutDetaching() sẽ giữ lại các giá trị đó. Chỉ update lại các ID truyền vào Ví dụ
user_id role_id module_name
1 1 A
1 2 B
1 3 C
1 4 D
1 5 E

Yêu cầu:

  • Thêm 1 module K và L với quyền lần lượt là Admin và Sub-Admin

Với yêu cầu như trên thì chúng ta hãy dùng method syncWithoutDetaching(). Mình trình bày như sau:

$user->role([1 => ['module_name' => 'K'], 2 => ['module_name' => 'L']);

Với một dòng lệnh này thì chúng ta có thể xử lí được yêu cầu phức tạp như trên phải không nào 😃

Như vậy là mình vừa giới thiệu 2 method xử lí trên quan hệ many-to-many. Trong bài viết tiếp theo thì mình giới thiệu 2 method nữa cũng khá hữu ích ! Chào các bạn nhé, hẹn gặp lại bài viết tiếp theo nào !!