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、权限
我想得到什么:
- 所有类别都包含说明其 ID 存在于 user_note table 中的特定用户 ID,并检查该行的 permission_id。
- 获取特定类别的所有笔记,其 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);
我正在使用 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、权限
我想得到什么:
- 所有类别都包含说明其 ID 存在于 user_note table 中的特定用户 ID,并检查该行的 permission_id。
- 获取特定类别的所有笔记,其 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);