我有一个标准的多对多关系
class User {
public function roles() {
return $this->belongsToMany('Role');
}
}
class Role {
public function users() {
return $this->belongsToMany('User');
}
}
它运作良好。
但我需要选择具有两个特定角色的所有用户。
$roleAdmin = Role::where('name', 'admin')->first();
$roleUser = Role::where('name', 'user')->first();
$users = //which users has BOTH $roleAdmin and $roleUser ??
是否有可能使用雄辩或我需要原始查询来实现这一目标?
PS用例是愚蠢的,我知道,它只是我真实问题的抽象(不涉及用户和角色)
答案 0 :(得分:1)
我找到的最佳解决方案是获取管理员和用户,然后使用intersect()
帮助程序仅获取$users
和admins
个集合中的用户:
$users = User::whereHas('roles', function ($q) use($otherRoles) {
$q->where('name', 'user')->whereNotIn('name', $otherRoles);
})->get();
$admins = User::whereHas('roles', function ($q) use($otherRoles) {
$q->where('name', 'admin')->whereNotIn('name', $otherRoles);
})->get();
$result = $admins->intersect($users);
如果你想保存一些内存,你可以pluck()
只有ID,intersect()
这些,然后只有whereIn()
的用户。
答案 1 :(得分:0)
这不是一个雄辩的解决方案(无论如何)
$users = \DB::table('users')
->select(\DB::raw("GROUP_CONCAT(roles.name SEPARATOR '-') as `role_names`"), 'users.name')
->join('role_user', 'users.id', '=', 'role_user.user_id')
->join('roles', 'roles.id', '=', 'role_user.role_id')
->groupBy('users.id')
->having('role_names', '=', 'admin-user')
->get();
admin-user
可以是user-admin
,其中角色名称首先出现在数据库中。请根据您的要求更改table
和column
名称