考虑Laravel:中的这种简单的多对多关系
class User extends Eloquent {
public function roles()
{
return $this->belongsToMany('Role');
}
}
和
class Role extends Eloquent {
public function users()
{
return $this->belongsToMany('User');
}
}
这对于保持user_id
和role_id
的role_user
的模式是可以的。但是,如果我们有其他的限制呢?例如,在像Github这样的应用程序中,用户在存储库A中是管理员,在存储库B中是普通用户。因此,我们将repository_id
添加到role_user
表中,但当我想查询user->roles
时,我想在当前存储库中查找它,我在会话中保留current_repository_id
的引用。要做到这一点,我应该对模型做哪些更改?
注意:我不想在使用代码时更改任何内容!难道不应该把过滤逻辑放在模型声明中吗?因为我正处于一个大项目的中间,很难改变每一种用法。有可能吗?
//User model
public function roles()
{
$repoID = MyApp::currentRepoID();
return $this->belongsToMany('Role', 'pivot_table_name', 'user_id', 'role_id')
->wherePivot('repository_id', $repoID);
}
如果需要向数据透视表添加其他字段,则应使用->withPivot()方法。如果您的数据透视表结构如下:
id | role_id | user_id | repository_id
你应该使用
return $this->belongsToMany('Role', 'pivot_table_name', 'user_id', 'role_id')->withPivot('repository_id');
然后,无论你在哪里使用它,你都必须这样做:
$role = Role::find(1);
$role->pivot->repository_id;
或
$user = User::find(1);
foreach ($user->roles as $role) {
echo $role->pivot->repository_id;
}
看看Eloquent Triple Pivot(也在Packagist上),它听起来正是你想要的。
您可以将模型设置为User
、Repository
和Role
(一个User
有许多Repository
,每个Role
都可以)。然后查看Github页面上的文档(特别是步骤6),您可以在Repository
模型上定义它:
class Repository extends Eloquent {
...
public function getRolesAttribute() {
return $this->getThirdAttribute();
}
}
然后你可以简单地调用
$user = User::find(1);
$repo = $user->repositories->first();
// or
$repo = $user->repositories->find(73);
$roles = $repo->roles;
// Or the above can be condensed into just...
$roles = User::findOrFail( 1 )
->repositories()
->findOrFail( 73 )
->roles;