Eloquent Many to Many选择没有特定角色的用户

时间:2016-05-20 12:58:35

标签: laravel eloquent laravel-5.2

所以我有User& Role模型具有多对多关系,我有3个角色:superadminmoderator,有4个用户,请说:{{1} },JohnMikeJames

LarryJohnsuperMikeadmin个角色,moderatorJames和{{ 1}}是admin。要显示没有特定角色的用户,我创建了此范围:

Larry

当我致电moderator以获取没有public function scopeDoesntHaveRoles($query, $roles = [], $column = 'id') { return $query->whereDoesntHave('roles')->orWhereHas('roles', function ($q) use ($roles, $column) { $q->whereNotIn($column, $roles); }); } 角色的用户时,它会运作并返回:

User::doesntHaveRoles([1])->lists('name', 'id')

但是,当我尝试列出没有super角色{"2":"Mike","3":"James","4":"Larry"} 的用户时,那里没有显示是admin但是他出现了User::doesntHaveRoles([2])->lists('name', 'id')实际上有James角色:

Mike

我认为这是因为admin也有{"1":"John","2":"Mike","4":"Larry"} 角色,您认为我的范围有问题吗?或者你有其他解决方案吗?

由于

修改 这是我的支点架构

Mike

moderator型号

Schema::create('user_roles', function (Blueprint $table) {
    $table->integer('user_id')->unsigned();
    $table->integer('role_id')->unsigned();

    $table->primary([
        'user_id', 'role_id'
    ]);
});

User模型

public function roles()
{
    return $this->belongsToMany(Role::class, 'user_roles');
}

1 个答案:

答案 0 :(得分:2)

我会使用whereNotIn代替whereDoesntHave

如果Role存储在变量$role中,您可以获得所有不具备该角色的用户:

/* @var Role $role */
User::whereNotIn(function('id', $query) use ($role) {
    $query->select('user_id')
        ->from('user_roles')
        ->where('role_id', $role->id);
});

内部查询将返回具有给定角色的所有用户ID。使用whereNotIn将返回相反的用户集。将创建以下查询:

select *
from users
where user_id not in (
    select user_id
    from user_roles
    where role_id = ?
);

现在Collection中存储了$roles个角色,您可以获得所有不具备以下任何角色的用户:

/* @var Collection|Role[] $roles */
User::whereNotIn(function('id', $query) use ($roles) {
    $query->select('user_id')
        ->from('user_roles')
        ->whereIn('role_id', $roles->pluck('id');
});

内部选择将返回在集合中具有其中一个角色的所有用户的ID。使用whereNotIn,您将再次获得相反的结果。您还可以使用一组角色ID而不是$roles->pluck('id')

构建器将创建一个类似

的查询
select *
from users
where user_id not in (
    select user_id
    from user_roles
    where role_id in (?, ?, ..)
);