雄辩的多对多关系

时间:2015-10-31 19:36:03

标签: php orm eloquent many-to-many

我正在使用Eloquent ORM,我有一个类别模型,通过多对多关系连接到 Note 模型。我还有一个用户模型,它通过多对多关系连接到注意模型,并通过一对多关系连接到类别模型。登记/> 数据库结构如下:
备注
id,title,content,created_at ....

类别
id,title,description

用户
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表中的特定用户ID,并检查该行的permission_id。
  2. 获取具有特定用户ID的user_note表中存在其ID的特定类别的所有注释,并检查该行的permission_id。
  3. 我写了一个方法来检查某个用户对某个笔记的权限(在注意模型中):

    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) - 此方法位于类别型号:

    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');
    

    现在,我收到一个错误:

      

    调用未定义的方法Illuminate \ Database \ Query \ Builder :: can()

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

1 个答案:

答案 0 :(得分:1)

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

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);