多对多和形式 Symfony2

Posted

技术标签:

【中文标题】多对多和形式 Symfony2【英文标题】:Many-To-Many and form Symfony2 【发布时间】:2014-01-16 21:22:16 【问题描述】:

我有什么

我有一个数据库表usuario(用户)和一个表perfil(配置文件),与一个perfiles_usuario(profiles_users)表相连。多对多的关系。我现在可以通过执行以下操作成功地从用户那里检索配置文件:$perfiles = $usuario->getPerfiles();

/**
 *
 * @return Perfil[]
 */
function getPerfiles()

    $perfiles = $this->getPerfilesCollection()->toArray();
    return $perfiles;

我想要做什么

我正在尝试制作表单,您可以在其中添加 perfil(配置文件)表中的一个或多个现有配置文件。我想要一个多选字段并为用户选择个人资料。

我想做什么

我的表单生成器

class UsuarioType extends AbstractType

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    

        $builder

            ->add('username', 'text', array('required' => false))

            ->add('perfiles', 'entity', array(
                'class' => 'UsuarioBundle:Perfil',
                'em' => 'dynamic_em',
                'query_builder' => function(EntityRepository $er) 

                    return $er->createQueryBuilder('c')->orderBy('c.nombre', 'ASC');

                , 
                'required' => false
            ))

        ;
    

我的看法

<div class="clearfix">
     form_widget(formulario.perfiles,  'attr':  'class': 'select-perfiles', 'multiple':''  )  
</div>

我的错误:

Catchable Fatal Error: Argument 1 passed to 
Centro\UsuarioBundle\Entity\Usuario::setPerfiles() must be of the type array, 
object given, called in C:\....\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php 
on line 345 and defined in C:\....\src\Centro\UsuarioBundle\Entity\Usuario.php line 450

Usuario.php 第 450 行

public function setPerfiles(array $perfiles) // line 450

    # Borra los perfiles que tiene el usuario
    $this->getPerfilesCollection()->clear();

    # Asigna los perfiles pasados por parámetro
    foreach ($perfiles as $perfil) 
        $this->addPerfil($perfil);
    

    return $this;

我认为问题出在我的用户 createAction 上:

$usuario = new Usuario();
$formulario = $this->crearCrearForm($usuario);
$formulario->handleRequest($request); <--------- ... at this line

这是表单数据

....
centro_extranetbundle_usuario[username]:test
centro_extranetbundle_usuario[perfiles]:9
centro_extranetbundle_usuario[perfiles]:4

【问题讨论】:

【参考方案1】:

第一个问题:setPerfiles的参数实例必须是Type集合(Doctrine接口) 第二个问题:perfiles 是一个集合,所以需要表单中的集合类型和 Perfiles 的 FormType。

【讨论】:

我已阅读 Symfony Docs symfony.com/doc/current/cookbook/form/form_collections.html 和 symfony.com/doc/current/reference/forms/types/collection.html 但我不知道如何获取多选字段“Perfil”(配置文件)的配置文件列表【参考方案2】:

非常感谢!这是解决方案

/**
 * Devuelve una coleccion con los perfiles del usuario
 *
 * @return ArrayCollection
 */
function getPerfiles()


    $perfiles = $this->getPerfilesCollection(); # ->toArray(); I delete this
    return $perfiles;

我也变了

/**
 * Establece los perfiles del usuario a partir de un ArrayCollection de
 * perfiles
 * 
 * @param ArrayColection
 *
 * @return self
 */
public function setPerfiles(ArrayCollection $perfiles)

    // # Borra los perfiles que tiene el usuario
    // $this->getPerfilesCollection()->clear();

    // # Asigna los perfiles pasados por parámetro
    // foreach ($perfiles as $perfil) 
    //     $this->addPerfil($perfil);
    // 

    // return $this;

    $this->getPerfilesCollection()->clear();

    foreach($collection->toArray() as $perfil)
        $this->addPerfil($perfil);
    

在表单生成器中,我只添加了这一行:'multiple' => true,

->add('perfiles', 'entity', array(
            'class' => 'UsuarioBundle:Perfil',
            'multiple' => true, <----------------------
            'em' => 'dynamic_em',
            'query_builder' => function(EntityRepository $er)

                return $er->createQueryBuilder('c')->orderBy('c.nombre', 'ASC');

            , 
            'required' => false
        ))

【讨论】:

很高兴能帮到你!还有一个建议:将 ArrayCollection 更改为 Collection(setPerfiles 参数实例)。原因是:有时使用 PersistantCollection 或 Proxy__ 类型的参数调用 setter。如果你只要求实现 Collection 接口,它会工作,否则你的应用会崩溃。

以上是关于多对多和形式 Symfony2的主要内容,如果未能解决你的问题,请参考以下文章

如何判断一对一对多和多对多的关系

具有一对多和多对多关系的 JOOQ pojos

多表关系一对多和多对多

MyBatis一对多和多对多xml配置

具有多对多和直通表的 Graphene-django

MySQL——一对多和多对多简单模型建表