我将用户角色存储到数据库时遇到问题。我使用的是原始文件:http://symfony.com/doc/current/book/security.html
在这里:http://symfony.com/doc/current/cookbook/security/entity_provider.html
登录注销正在运行。我可以将用户保存到数据库中,但我不知道如何保存他的角色。是否有可能使用这些文件,或者我还需要再做一个单独服务的文件?我不想使用FOSUser Bundle ...谢谢你的回答。这是链接:
的AccountController http://pastebin.com/ycrLyUcg
注册 http://pastebin.com/Q7se6pnF
RegistrationType http://pastebin.com/926tu0hj
用户 http://pastebin.com/aNdQr46C 角色 http://pastebin.com/cg7QTk59 UserRepository http://pastebin.com/LHPuy4We
非常感谢您的回答
编辑10.11.2013 23:00:
EDIT 11.11.2013 15:20
答案 0 :(得分:8)
在您的AccountController的createAction
方法中,您实际上从未向用户分配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);
...
}
另外,我会重新考虑在用户与角色之间建立@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
类也为其用户对象使用了一组角色,因此一旦您拥有角色,您就可以只使用现有的{{3}希望一切都能正常运作。如果不是,您可能必须自定义身份验证提供程序。
请注意,在上面我们明确地使用$roles
方法分配setRoles()
属性;这是因为getRoles()
的返回类型不是ArrayCollection
,而是原始array
。如果您希望所有内容都能与Symfony现有的身份验证提供程序“正常工作”,并且getRoles()
返回原始数组是正确的。
“我按你写的那样做了,但它试图写入acme_roles表,我保存角色类型 - admin,user ....但是我想将用户的角色保存到user_roles表中 - 我保存了用户ID和角色ID “
鉴于您在聊天中的扩展评论中表达了您想要的内容,我的方法是使用三个实体/表来模拟您的用户与角色之间的关系。这显然只是解决问题的一种方法。
您的表格为:acme_users
(User
实体),acme_roles
(Role
实体)和acme_user_roles
(UserRole
实体)
User
与Role
个对象没有直接的多对多关系,而是User
对象之间可能存在一对多关系{1}}和UserRole
类。UserRole
(或者你称之为的任何关系)需要一个主键(id
)和两个多对一关系:一个用于User
和一个对于Role
。Role
类和UserRole
之间创建反向关系,因为您的角色与其他实体隔离开来。Role
分配User
之前,您需要先查找它,一旦找到它,您就可以创建UserRole
并引用您的{{1}然后将{}添加到$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()
中,您希望存储实体引用而不是ID(由于Doctrine,它们将以任何方式映射为列中的ID),因此只需更改setRoles()
和{{ 1}}分别改为UserRole
和$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
查找正确且相应的角色),并将其分配给您的{{ 1}},然后将Role
分配给AccoundController
,最后保留ROLE_USER
,例如:
UserRole
确保重新生成架构,最直接的方法是运行:
UserRole
答案 1 :(得分:1)
所以问题解决了。我使用了本教程中的文件:http://symfony.com/doc/current/cookbook/security/entity_provider.html。而且我必须这样做:
$ 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
谢谢Sean Quinn