我和你之间有一种多对多的关系 User
以及 Role
并希望检查用户是否具有给定列表中的任何角色。
所以我在模型上输入:
public function hasAnyRoles(array $roles) {
return $this->roles()->whereIn('name', $roles)->exists();
}
继续 UserController
:
// User has only "manager" role.
$user->hasAnyRoles(['admin', 'manager']) // true
问题是,在某些部分,我需要验证用户是否拥有给定列表中的所有角色。例如:
// User has only "manager" role.
$user->hasRoles(['admin', 'manager']) // false
我是用“懒惰”的方式写的,这会产生 n + 1
查询:
public function hasRolesLazy($roles) {
return array_reduce($roles, function ($initial, $role) {
return $this->roles()->where('name', $role)->exists();
}, false);
}
怎样 hasRoles(array $roles)
方法必须构造为只执行数据库中的一个查询?我是sql的新手,所以我想不出多少解决方案。
2条答案
按热度按时间kmbjn2e31#
试试这个:
lnxxn5zx2#
我的建议是,一旦使用关系,就为用户加载所有角色。当您通过像属性一样调用关系来加载关系时,laravel会将其缓存在引擎盖下,这样它就不会重复任何查询。然后,您可以简单地使用加载的角色来实现两种方法:
第二种方法是:
当然,有许多不同的方法来实现这些方法,特别是在
Collection
类将帮助您,但关键是使用$this->roles
只产生一个查询。