3

我有一个与角色实体具有多对多关系的 Doctrine 用户实体。我还有一个表单,它根据用户实体字段在其中显示用户详细信息。我正在以正常方式设置表单,在我的控制器中使用表单构建器,并传入从数据库加载的实体实例。这一切都很好。

现在,我想要的是此表单中的选择菜单,其中包含用户分配给选定的角色,并从数据库中的可用角色中填充。我在我的UserType表单中创建了一个名为roles“集合”类型的字段,并在RoleType表单实例中传递。在我的RoleType表单中,我添加了一个带有类型的字段entity并定义了我的角色类等。这一切都按照文档进行。这一切都很好,它加载了填充了角色的选择菜单,但它没有选择针对用户实体保存的正确角色。

当我跟踪“角色”的表单值(或在我的角色实体字段上设置数据转换器)时,我得到的值是一个包含与用户关联的角色名称的字符串。我没有得到角色实例或集合/数组。此外,如果我将角色实体字段设置为multiple = true,我会收到Expected a Doctrine\Common\Collections\Collection object.来自学说数据转换器的错误。同样,这是因为它期待一个集合并获得一个字符串。

这可能与我的用户实体被水合的方式有关吗?我正在使用$repository->findOneBy(array('id' => $id))

这是我正在做的简化版本:

用户类

class User implements AdvancedUserInterface, \Serializable
{   
    /**
     * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
     */
    public $roles;

    public function __construct()
    {
        $this->roles = new ArrayCollection();
    }

    public function getRoles()
    {
        return $this->roles->toArray();
    }
}

角色类

class  Role implements RoleInterface
{
    /**
     * @ORM\ManyToMany(targetEntity="User", inversedBy="roles")
     */
    public $users;

    public function __construct()
    {
        $this->users = new ArrayCollection();
    }

    public function getUsers()
    {
        return $this->users;
    }
}

用户表单类型

class UserType extends AbstractType
{
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'NameSpace\MyBundle\Entity\User',
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('id', 'hidden')
            ->add('roles', 'collection', array('type' => new RoleType()))
            ->add('save', 'submit');
     }

     public function getName()
     {
         return 'user';
     }
}

角色表格类型

class RoleType extends AbstractType
{
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'NameSpace\MyBundle\Entity\Role',
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', 'entity', array(
            'class' => 'NameSpace\MyBundle\Entity\Role', 
            'property' => 'name'
            [multiple  => true]
        ));
    }

    public function getName()
    {
       return 'role';
    }
}
4

1 回答 1

4

您没有从用户实体为您的表单提供角色集合:

public function getRoles()
{
    //this returns an array
    return $this->roles->toArray();
}

表单类使用实体中的 getter 和 setter,因此您实际上返回了一个数组,因为这正是 Symfony2 安全系统所需要的。您还需要实现一个 getRolesCollection 字段并在表单中使用它:

public function getRolesCollection()
{
    //this returns a collection
    return $this->roles;
}

//and (updated from comment below)
->add('roles_collection', 'entity', array('type' => new RoleType()))

oro 平台执行以下操作:https ://github.com/orocrm/platform/blob/master/src/Oro/Bundle/UserBundle/Form/Type/UserType.php

这篇博文也可能有帮助:http : //blog.jmoz.co.uk/symfony2-fosuserbundle-role-entities/ 这是一个在 FOSUserBundle 的数据库中添加角色的人

于 2013-11-05T09:05:00.600 回答