Symfony2:如何验证和持久化实体数组(集合形式)?

时间:2016-01-11 15:03:31

标签: php arrays forms symfony

在我的应用程序中,我有一个嵌入表单集合的主表单。

我的目标是让一个网页上有一个网格表单,每行包含一个Category实体的不同实例,并且在行value1value2value3

我成功创建Category formtype,Categories formtype,这是Category表单的集合,页面中表单的呈现工作正常,其中的值表格匹配持久数据。

以下是代码:

的Acme \的appbundle \表格\型号\ Category.php     ...

class CategoryType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder -> add ( 'value1' , 'text' )
                 -> add ( 'value2' , 'text' )
                 -> add ( 'value3' , 'text' )
                 -> add ( 'id', 'hidden')
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\APPBundle\Entity\Category',
        ));
    }

    public function getName()
    {
        return 'category';
    }
}
...

的Acme \的appbundle \表格\型号\ Category.php

class CategoriesType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('categories', 'collection', array('type' => new CategoryType()))
                ->add('save','submit');
    }


    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'validation_groups' => false
        ));
    }

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

的Acme \的appbundle \控制器\ MainController.php

public function categoriesAction ( ) {
    $em = $this -> getDoctrine ( ) -> getManager ( );

    $categories = $em->getRepository('Acme\APPBundle\Entity\Category')->findAll();

    $form = $this -> createForm ( new CategoriesType ( ) , array('categories'=>$categories) );
    $form -> handleRequest ( $this -> getRequest ( ) );

    if ( $form -> isValid ( ) ) {
        $em -> persist ( $form );
        $em -> flush ( );
    }

    return $this -> render (
        'AcmeAPPBundle:Admin:categories.html.twig' , 
        array ( 
            'form' => $form -> createView(),
        )
    );
 }

我现在的问题是我无法在表单中保留修改过的数据。 我的控制器中的$form -> isValid ( )返回false。 我尝试了“手动”验证:

$validator = $this      -> get ( 'validator' );
$errorList = $validator -> validate ( $form );

但我没有任何错误,但表单仍被视为无效。 我还尝试绕过验证并直接保存数据但没有任何反应。

有任何线索吗?感谢

2 个答案:

答案 0 :(得分:2)

请尝试以下步骤来传递验证。

  • 将数据类设置为CategoriesType表单。
  • 添加"有效"对类别实体中的类别字段的约束,这也将验证子类。
  • 要进行调试,要从子类中打印错误,请尝试 $形式 - > getErrors(真)
  • Cascade persist使用$ em-> persist($ categories)对类别实体实例进行分类。 请注意,您无法保留表单对象。

这可以解决您的问题。

答案 1 :(得分:0)

谢谢@ satdev86的建议。

遗漏的内容可能是cascade_validation以及我试图保留$form而不是数据的事实。

以下是我可能感兴趣的功能代码:

的Acme \的appbundle \表格\型号\ Category.php

...
class CategoryType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder -> add ( 'value1' , 'text' )
                 -> add ( 'value2' , 'text' )
                 -> add ( 'value3' , 'text' )
                 -> add ( 'id', 'hidden')
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\APPBundle\Entity\Category',
            'csrf_protection' => false,
            'cascade_validation' => true,
        ));
    }

    public function getName()
    {
        return 'category';
    }
}
...

的Acme \的appbundle \表格\型号\ Categories.php

...
class CategoriesType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('categories', 'collection', array('type' => new CategoryType()))
                ->add('save','submit');
    }


    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'validation_groups' => false,
            'csrf_protection' => false,
            'cascade_validation' => true,
        ));
    }

    public function getName()
    {
        return 'categories';
    }
}
...

的Acme \的appbundle \控制器\ MainController.php

...
public function categoriesAction ( ) {
    $em = $this -> getDoctrine ( ) -> getManager ( );

    $categories = $em->getRepository('Acme\APPBundle\Entity\Category')->findAll();

    $form = $this -> createForm ( new CategoriesType ( ) , array('categories'=>$categories) );
    $form -> handleRequest ( $this -> getRequest ( ) );

    if ( $form -> isValid ( ) ) {
        foreach($form -> getData()['categories'] as $c) {
            $em -> persist ( $c );
        }
        $em -> flush ( );
    }

    return $this -> render (
        'AcmeAPPBundle:Admin:categories.html.twig' , 
        array ( 
            'form' => $form -> createView(),
        )
    );
 }
...