Symfony 4 Doctrine 多个 table 加入一个 属性
Symfony 4 Doctrine multiple table joins in one property
symfony 和 Doctrine 的新手。我的数据库中有以下 tables。
mo_user
id | email | password
__________________________________
9144 | summer@h.com | !password!
mo_user_角色
user_id| role_id
_________________
9144 | 5
mo_permission
id | namespace | name | description
______________________________________________
1 | admin | - | -
2 | users | - | -
3 | view_summary_report | - | -
4 | view_user_statement | - | -
mo_role_permission
role_id | permission_id
________________________
5 | 3
5 | 4
我正在尝试 return 当前用户的权限数组,在本例中,id = 9144
的用户应该是 array('view_summary_report','view_user_statement')
。
我已将所有 table 映射到它们对应的实体 class。在对应于 mo_user
table 的 MoUser.php
实体 class 中,我有一个
应该 return 数组的权限方法,但我从注释中加入失败,
我的 getPermissions()
方法 MoUser.php
/**
* @var Collection|MoPermission[]
* @ORM\ManyToMany(targetEntity="App\Entity\MoPermission")
* @ORM\JoinTable(
* name="mo_user_role",
* joinColumns={@ORM\JoinColumn(name="user_id",referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="role_id",referencedColumnName="id")}
* )
*/
private $permissions;
public function getPermissions()
{
$currentPermissions = array();
foreach ($this->permissions->toArray() as $index => $permission) {
$currentPermissions[] = $permission->getNamespace();
}
//Return default role if Roles are not assigned to this user.
if(count($currentPermissions)>0) {
return $currentPermissions;
} else {
return array('DEFAULT_PERMISSION');
}
}
所以我想出了原始 sql 来实现下面我想要的,但我想知道实现以下原始 SQL 的 Symfony/Doctrine 注释方法。
SELECT t0.id AS id_1, t0.namespace AS namespace_2, t0.name AS name_3, t0.description AS description_4
FROM mo_permission t0
LEFT JOIN mo_role_permission ON t0.id = mo_role_permission.permission_id
LEFT JOIN mo_user_role ON mo_role_permission.role_id = mo_user_role.role_id
WHERE mo_user_role.user_id = 9144;
我认为没有合适的方法可以直接通过 属性 注释和您当前的设置来实现您想要做的事情。
您可以使用以下解决方案之一实现您想要的效果:
不需要 mo_user_role
和 mo_role_permission
之一,因为其中 none 有附加字段。您应该只拥有一个由 MoUser
和 MoPermission
之间的 ManyToMany
关系生成的 mo_user_permission
table,这将授予您直接访问 MoPermission
的权限MoUser
的getPermissions()
另一种方法是创建一个具有 GetPermissionsFromUser(MoUser $moUser)
方法(例如)的服务,从实体的存储库中调用适当的查询,您可以在需要时调用该查询。
您仍然可以使用当前设置在 getPermissions()
方法中实现您想要的结果,但是您必须遍历每个关系的项目以手动构建新的结果数组。
例如最后一点:
public function getPermissions() {
$permissions = [];
foreach($this->roles as $role) {
foreach($role->getPermissions() as $permission) {
permissions[] = $permission->getNamespace();
}
}
return $permissions;
}
这假设您有一个 MoRole 实体,这对您当前的设置很有意义,但您没有提到它。否则,仍然可以应用相同的逻辑,这只是命名问题。
我很确定您可以使用 Doctrine(和 QueryBuilder)来执行该查询,例如...
use Doctrine\ORM\EntityRepository
class PermissionRepository extends EntityRepository
{
//....
/**
* @param UserInterface $user
* @return array|Permission[]
*/
public function getPermissionsForUser(UserInterface $user)
{
$queryBuilder = $this->createQueryBuilder('permission');
/**
* permissions will be in a multi-dimensional array
* with a single key per array of 'namespace'
*/
$permissions = $queryBuilder
->select('permission.namespace')
->join('permission.role', 'role')
->join('role.user', 'user')
->where($queryBuilder->expr()->eq('user', ':user'))
->setParameter('user', $user)
->getQuery()
->getArrayResult();
if (count($permissions) > 0) {
/**
* If there are any permissions found just return
* the 'namespace' property from each "sub-array"
*/
return array_column($permissions, 'namespace');
}
return ['DEFAULT_PERMISSION'];
}
//...
}
然后你会这样称呼它..
$permissions = $repository->getPermissionsForUser($user);
symfony 和 Doctrine 的新手。我的数据库中有以下 tables。
mo_user
id | email | password
__________________________________
9144 | summer@h.com | !password!
mo_user_角色
user_id| role_id
_________________
9144 | 5
mo_permission
id | namespace | name | description
______________________________________________
1 | admin | - | -
2 | users | - | -
3 | view_summary_report | - | -
4 | view_user_statement | - | -
mo_role_permission
role_id | permission_id
________________________
5 | 3
5 | 4
我正在尝试 return 当前用户的权限数组,在本例中,id = 9144
的用户应该是 array('view_summary_report','view_user_statement')
。
我已将所有 table 映射到它们对应的实体 class。在对应于 mo_user
table 的 MoUser.php
实体 class 中,我有一个
应该 return 数组的权限方法,但我从注释中加入失败,
我的 getPermissions()
方法 MoUser.php
/**
* @var Collection|MoPermission[]
* @ORM\ManyToMany(targetEntity="App\Entity\MoPermission")
* @ORM\JoinTable(
* name="mo_user_role",
* joinColumns={@ORM\JoinColumn(name="user_id",referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="role_id",referencedColumnName="id")}
* )
*/
private $permissions;
public function getPermissions()
{
$currentPermissions = array();
foreach ($this->permissions->toArray() as $index => $permission) {
$currentPermissions[] = $permission->getNamespace();
}
//Return default role if Roles are not assigned to this user.
if(count($currentPermissions)>0) {
return $currentPermissions;
} else {
return array('DEFAULT_PERMISSION');
}
}
所以我想出了原始 sql 来实现下面我想要的,但我想知道实现以下原始 SQL 的 Symfony/Doctrine 注释方法。
SELECT t0.id AS id_1, t0.namespace AS namespace_2, t0.name AS name_3, t0.description AS description_4
FROM mo_permission t0
LEFT JOIN mo_role_permission ON t0.id = mo_role_permission.permission_id
LEFT JOIN mo_user_role ON mo_role_permission.role_id = mo_user_role.role_id
WHERE mo_user_role.user_id = 9144;
我认为没有合适的方法可以直接通过 属性 注释和您当前的设置来实现您想要做的事情。
您可以使用以下解决方案之一实现您想要的效果:
不需要
mo_user_role
和mo_role_permission
之一,因为其中 none 有附加字段。您应该只拥有一个由MoUser
和MoPermission
之间的ManyToMany
关系生成的mo_user_permission
table,这将授予您直接访问MoPermission
的权限MoUser
的getPermissions()
另一种方法是创建一个具有
GetPermissionsFromUser(MoUser $moUser)
方法(例如)的服务,从实体的存储库中调用适当的查询,您可以在需要时调用该查询。您仍然可以使用当前设置在
getPermissions()
方法中实现您想要的结果,但是您必须遍历每个关系的项目以手动构建新的结果数组。
例如最后一点:
public function getPermissions() {
$permissions = [];
foreach($this->roles as $role) {
foreach($role->getPermissions() as $permission) {
permissions[] = $permission->getNamespace();
}
}
return $permissions;
}
这假设您有一个 MoRole 实体,这对您当前的设置很有意义,但您没有提到它。否则,仍然可以应用相同的逻辑,这只是命名问题。
我很确定您可以使用 Doctrine(和 QueryBuilder)来执行该查询,例如...
use Doctrine\ORM\EntityRepository
class PermissionRepository extends EntityRepository
{
//....
/**
* @param UserInterface $user
* @return array|Permission[]
*/
public function getPermissionsForUser(UserInterface $user)
{
$queryBuilder = $this->createQueryBuilder('permission');
/**
* permissions will be in a multi-dimensional array
* with a single key per array of 'namespace'
*/
$permissions = $queryBuilder
->select('permission.namespace')
->join('permission.role', 'role')
->join('role.user', 'user')
->where($queryBuilder->expr()->eq('user', ':user'))
->setParameter('user', $user)
->getQuery()
->getArrayResult();
if (count($permissions) > 0) {
/**
* If there are any permissions found just return
* the 'namespace' property from each "sub-array"
*/
return array_column($permissions, 'namespace');
}
return ['DEFAULT_PERMISSION'];
}
//...
}
然后你会这样称呼它..
$permissions = $repository->getPermissionsForUser($user);