我的
User
实体实现了UserInterface
,因此提供了getRoles()
方法。在我的系统中,一个 User
可以属于多个 Group
。一个组可以有多个角色。因此,可以通过收集所有组并合并这些组角色的列表来确定用户的角色。 FOSUserBundle也可以实现同样的效果。
最简单的算法是:
public function getRoles()
{
$roles = $this->roles;
foreach ($this->getGroups() as $group) {
$roles = array_merge($roles, $group->getRoles());
}
return array_unique($roles);
}
我认为这个解决方案是有问题的,因为它的扩展性会很差。对于每个组都必须执行新的查询,因此查询的数量取决于组的数量。
通常我会通过定义一个查询来解决这个问题,该查询收集用户的所有组并加入组的角色。这需要从
UserRepository
实体调用 User
(或直接构建 Doctrine 查询),我认为这是一个不好的做法。
那么如何在保持单个连接查询的性能优势的同时避免这种不好的做法呢?
(这次我很难找到一个合适的问题标题。我不确定是否还有其他类似的情况,但我不这么认为,因为通常我会在存储库本身中提供这样的方法。在在这种情况下,
UserInterface
要求它位于实体中)
最简单的方法是创建一个自定义 UserProvider。
请参阅 http://symfony.com/doc/current/security/custom_provider.html#create-a-user-provider 了解文档。
在此用户提供程序中,您必须进行查询以从用户名中选择用户并将加入添加到组实体,因此您只有一个查询