在您的 AccountController 的createAction
方法中,您实际上从未将 a 分配Role
给用户;您必须先设置它,然后才能将其用作身份验证过程的一部分。Role
给定您的上述模型,这样的事情应该持续存在。
if ($registrationForm->isValid()) {
...
$role = new Role();
$role->setName('User');
$role->setRole('ROLE_USER');
$roles = new \Doctrine\Common\Collections\ArrayCollection;
$roles->add($role);
$user->setRoles($roles);
...
}
另外,我会重新考虑在Users和Roles@ManyToMany
之间建立关系的要求,在这里可能就足够了;无论您是否希望坚持使用任何类型的关联映射,您都可能需要确保在持久化类时关联的角色也被持久化。为此,您可能需要在课堂上添加指令,如下所示:@ManyToOne
User
cascade
User
class User implements AdvancedUserInterface, \Serializable
{
...
/**
* @ORM\ManyToMany(targetEntity="Role", inversedBy="users", cascade={"all"})
*/
private $roles;
...
}
中的默认User
类Symfony\Component\Security\Core\User
还为其用户对象使用角色集合,因此一旦您拥有持久的角色,您就可以只使用现有的UsernameAuthenticationProvider,希望一切都能正常工作。如果不是,您可能必须自定义身份验证提供程序。
请注意,在上面我们使用方法显式分配$roles
属性setRoles()
;这是因为返回类型getRoles()
不是ArrayCollection
,而是原始类型array
。如果您希望一切都与 Symfony 现有的身份验证提供程序一起“正常工作”,并且getRoles()
返回原始数组据我所知是正确的。
重新审视同一问题(2013 年 11 月 10 日):
“我按照你写的做了,但它试图写入 acme_roles 表,我在其中保存角色类型 - 管理员、用户 .... 但我想将用户的角色保存到 user_roles 表中 - 我在那里保存用户 ID和角色ID “
鉴于您在聊天中的扩展评论中表明您想要的内容,我的方法是使用三个实体/表来模拟您的用户到角色的关系。这显然只是解决问题的一种方法。
您的表将是:(acme_users
实体User
)、acme_roles
(Role
实体)和acme_user_roles
(UserRole
实体)。
- 您
User
不会直接与您的对象建立多对多关系Role
,而是可以在 the和类之间建立一对多关系。User
UserRole
- 关联类
UserRole
(或任何你称之为的)需要一个主键 ( id
) 和两个多对一关系:一个用于 the User
,一个用于Role
.
- 无需在
Role
类和之间创建反向关系UserRole
,因为您的角色与其他实体隔离。
- 在将 a 分配
Role
给您新创建的之前,User
您需要先查找它,一旦找到它,您可以使用您UserRole
的引用创建您的$user
,$role
然后将其添加到您在User
班级中的角色集中。
以上只是您如何解决问题的粗略概述;更详细地说:
您的类应通过注释User
将关系映射到实体,例如:UserRole
@ORM\OneToMany
/**
* @ORM\OneToMany(targetEntity="UserRole", mappedBy="user", cascade={"all"})
*/
private $userRoles;
在User
中,更改您的getRoles()
方法以返回与 关联的实际角色UserRoles
,类似于:
/**
* @inheritDoc
*/
public function getRoles()
{
$roles = array();
foreach ($this->userRoles as $userRole) {
$roles[] = $userRole->getRole();
}
return $roles;
}
在User
类中,添加getUserRoles()
,setUserRoles()
(可能还有一个addUserRole()
)方法,删除setRoles()
在UserRole
中,您想要存储实体引用而不是 ID(由于 Doctrine,它们将以任何方式映射为列中的 ID),因此只需分别更改$user_id
和$role_id
到$user
和$role
,并更改它们的映射(如果您希望多个角色可分配通过UserRole
关联,您需要有一个离散的身份/主键,因此添加$id
属性),如下所示:
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="userRoles", cascade={"all"})
*/
private $user;
/**
* @ORM\ManyToOne(targetEntity="Role", cascade={"all"})
*/
private $role;
$users
从您的Role
班级中删除所有引用。
在 中AccoundController
,查找您要分配的角色(即,如果您要分配ROLE_USER
查找正确和相应的角色),并将其分配给您的UserRole
,然后将您的分配UserRole
给您的User
,最后坚持您的$user
,例如:
$user = $registration->getUser();
$user->setSalt($this->generateSalt());
$user->setIsActive(1);
$factory = $this->get('security.encoder_factory');
$encoder = $factory->getEncoder($user);
$password = $encoder->encodePassword($user->getPassword(), $user->getSalt());
$user->setPassword($password);
$role = $this->getDoctrine()
->getRepository('AcmeAccountBundle:Role')
->find(2); // Finds "ROLE_USER"
$userRole = new UserRole();
$userRole->setRole($role);
$user->addUserRole($userRole);
$em->persist($user);
$em->flush();
确保重新生成架构,最直接的方法是运行:
$ php app/console doctrine:database:drop --force
$ php app/console doctrine:database:create
$ php app/console doctrine:schema:drop --force
$ php app/console doctrine:schema:create
$ php app/console doctrine:schema:validate