简体   繁体   English

Laravel:对多对多关系添加约束

[英]Laravel: add constraint on many-to-many relationships

Consider this simple many-to-many relationship in Laravel: 考虑一下Laravel中这种简单的多对多关系:

class User extends Eloquent {
    public function roles()
    {
        return $this->belongsToMany('Role');
    }
}

and

class Role extends Eloquent {
    public function users()
    {
        return $this->belongsToMany('User');
    }
}

This is ok with schema of role_user that keeps user_id and role_id . 对于保留了user_idrole_idrole_user模式,这是可以的。 But what we if have some other constraints? 但是,如果还有其他限制,我们该怎么办? For example in an app like Github, user is admin in repository A and is regular user in repository B. So we add repository_id to role_user table, but when I want to query user->roles I want to look for that in current repository, that I keep reference of current_repository_id in session . 例如,在类似Github的应用中,用户在存储库A中是admin,在存储库B中是普通用户。因此,我们将repository_id添加到role_user表中,但是当我要查询user->roles我想在当前存储库中查找它我在session中保留对current_repository_id引用 What changes should I do in models to do that? 我应该在模型中进行哪些更改来做到这一点?


Note: I don't want to change anything in using-code! 注意:我不想更改使用代码中的任何内容! Isn't anyway to put filter logic in model declaration? 反正不是在模型声明中放入过滤器逻辑吗? Because I'm at the middle of big project and it's tough to change every usage. 因为我处于大型项目的中间,因此很难更改每种用法。 Is it possible? 可能吗?

//User model 
public function roles()
{
    $repoID = MyApp::currentRepoID();

    return $this->belongsToMany('Role', 'pivot_table_name', 'user_id', 'role_id')
        ->wherePivot('repository_id', $repoID);
}

If you need to add additional fields to the pivot table, you should use ->withPivot() method. 如果需要向数据透视表添加其他字段,则应使用-> withPivot()方法。 If your pivot table structure is like: 如果您的数据透视表结构如下:

id | id | role_id | role_id | user_id | user_id | repository_id repository_id

you should use 你应该使用

return $this->belongsToMany('Role', 'pivot_table_name', 'user_id', 'role_id')->withPivot('repository_id');

Then, wherever you use it, you have to do: 然后,无论在哪里使用它,都必须执行以下操作:

$role = Role::find(1);
$role->pivot->repository_id;

or 要么

$user = User::find(1);
foreach ($user->roles as $role) {
    echo $role->pivot->repository_id;
}

Check out Eloquent Triple Pivot (also on Packagist), it sounds like it does exactly what you want. 看看Eloquent Triple Pivot (也在Packagist上),听起来像它确实满足您的要求。

You'd set up your Models as User , Repository and Role (a User has many Repository s and can have a Role in each). 您将模型设置为UserRepositoryRole (一个User有多个Repository并且每个Role都可以有一个Role )。 Then look at the docs on the Github page (particularly step 6), and you'd define this on your Repository model: 然后查看Github页面上的文档(尤其是步骤6),然后在Repository模型中定义它:

class Repository extends Eloquent {
    ...
    public function getRolesAttribute() {
        return $this->getThirdAttribute();
    }
}

Then you can simply call 然后,您可以简单地致电

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM