Symfony2, validation embedded and non-embedded for

2019-09-01 20:48发布

问题:

I have this form builder:

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('task', 'text', array('label' => 'Task'))
                ->add('dueDate', 'date', array('label' => 'Date', 'format' => 'ddMMMMyyyy'))
                ->add('category', 'entity', array('required' => true, 'multiple' => true, 'class' => 'AcmeTaskBundle:Category', 'query_builder' => function($repository) { return $repository->createQueryBuilder('c')->orderBy('c.id', 'ASC'); },))
                ->add('save', 'submit', array('label' => 'Send'));
    }

and it works successful with this controller:

if($form->isValid())
{
    $this->get('session')->getFlashBag()->add(
        'success',
        'Task successfuly added'
    );
    $em = $this->getDoctrine()->getManager();
    foreach($form->get('category')->getData() as $cat)
    {
        $task->removeCategory($cat);
        $task->addCategory($cat);
    }
    $em->persist($task);
    try {
        $em->flush();
    } catch (\PDOException $e) {
        // sth
    }
}

BUT

if I try to embed my form with field category like this:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('task', 'text', array('label' => 'Task'))
            ->add('dueDate', 'date', array('label' => 'Date', 'format' => 'ddMMMMyyyy'))
            ->add('category', new CategoryType())
            ->add('save', 'submit', array('label' => 'Send'));
}

where my CategoryType looks like:

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

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('name', 'entity', array(
                  'class' => 'AcmeTaskBundle:Category',
                  'query_builder' => function($repository) { return $repository->createQueryBuilder('c')->orderBy('c.id', 'ASC'); },
                  //'property' => 'name',
                  'multiple' => true,
                  'required' => true,
                  ));
}

it returns an Exception instance of Category expected, ArrayCollection given. Why the "same" form is working only if it is not embedded?

回答1:

These two types are not the same. In the first case you use option 'multiple' => true that means that form expects collection of Category entity. From your controller I see that you have (One|Many)-To-Many relation Task-Category. Category here is ArrayCollection of Category entities and therefore your form is working.

In the second case you have ->add('category', new CategoryType()) that means that Category can be the only one, according to your controller and Task entity it is not true. You need to create collection of CategoryType() here.

->add('category', 'collection', array('type' => new CategoryType()))

Also I think you must provide this line with more options to fit your application.