Eloquent 多对多关系

Eloquent Many to many relationship

我正在使用 Eloquent ORM,我有一个 Category 模型,它通过 [=79] 连接到 Note 模型=]关系。我还有一个 User 模型,它通过多对多关系连接到 Note 模型和 Category 一对多关系建模。
数据库结构如下:
笔记
id, 标题, 内容, created_at.....

类别
ID、标题、描述

用户
id, first_name, last_name...

note_user
user_id、note_id、permission_id

category_note
category_id、note_id

note_permissions
permission_id、权限

我想得到什么:

  1. 所有类别都包含说明其 ID 存在于 user_note table 中的特定用户 ID,并检查该行的 permission_id。
  2. 获取特定类别的所有笔记,其 ID 存在于 user_note table 中,并具有特定用户 ID,并检查该行的 permission_id。

我写了一个方法来检查某个用户对笔记有什么权限(在Note模型中):

public function can($uid, $perm)
{
    $users = $this->users()->get();
    foreach ($users as $user) {
        if ($user->id == $uid) { // this user is shared
            $permId = $user->pivot->permission_id;
            $permissions = NotePerm::find($permId)->permissions;
            $perm = 'note.' . $perm;
            if (array_key_exists($perm, $permissions) && $permissions[ $perm ])
                return true;
        }
    }
    return false;
}

我的想法是获取所有包含某个用户可以看到的笔记的类别(这意味着 user_note 中有一行包含他的用户 ID 和属于该类别的笔记 ID)- 这个方法放在Category model:

public function scopeWithNotesCan($query, $uid, $perm)
{
    return $query->whereHas('notes', function ($query) use ($uid, $perm) {
        $query->can($uid, $perm);
    });
}

这是调用:

$categories->WithNotesCan($this->user->id, 'view');

现在,我收到一个错误:

Call to undefined method Illuminate\Database\Query\Builder::can()

如何在获取所有笔记之前使用自定义方法检查每个笔记?

通过使用多个 whereHas 来完成。在 Category 模型中,添加了以下范围:

public function scopeForUser($query, $uid, $perm = 'view')
{
    return $query->whereHas('notes', function ($query) use ($uid, $perm) {
        $query->forUser($uid, $perm)->orWhere('private', '=', false);
    });
}

注意模型中,添加了以下作用域:

public function scopeForUser($query, $uid, $perm = 'view')
{
    $permissions = NotePerm::findWhere($perm);
    return $query->whereHas('users', function ($query) use ($uid, $permissions) {
        $query->where('note_user.user_id', $uid)->whereIn('note_user.permission_id', $permissions)->orWhere('private', '=', false);
    });
}

findWhere NotePerm 方法获取包含特定权限字符串的所有权限的数组:

public function scopeFindWhere($query, $perm = 'view')
{
    $permissions = self::all();
    $perm = 'note.' . $perm;
    return $permissions->filter(function ($item) use ($perm) {
        return array_key_exists($perm, $item->permissions) && $item->permissions[ $perm ];
    })->lists('id')->toArray();
}

因此要获取与特定用户共享的所有类别($user 是类别的所有者,而不是我们正在搜索的特定用户):

$user->categories()->forUser($this->user->id, $perm);

要获取与特定用户共享的特定类别的所有笔记:

$user->categories()->forUser($this->user->id, $perm)->notes()->forUser($this->user->id, $perm);