0

问题

我一直在尝试按照教程将表单嵌入到另一个表单中。我在这里尝试做的是添加一个任务,并为其添加多个类别。我正在使用http://symfony.com/doc/current/book/forms.html#embedding-a-single-object上的示例,但我添加了一些 ORM 注释以使关系成为多对多。因此,这是我的任务和类别实体的代码:

代码

任务实体

<?php

namespace Acme\TaskBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Task
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Task
{
    /**
     * @ORM\ManyToMany(targetEntity="Category", inversedBy="tasks")
     * @ORM\JoinTable(name="tasks_categories")
     *
     * @Assert\Type(type="Acme\TaskBundle\Entity\Category")
     */
    protected $categories;

    // ...



    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;


    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Task
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->categories = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add categories
     *
     * @param \Acme\TaskBundle\Entity\Category $categories
     * @return Task
     */
    public function addCategorie(\Acme\TaskBundle\Entity\Category $categories)
    {
        $this->categories[] = $categories;

        return $this;
    }

    /**
     * Remove categories
     *
     * @param \Acme\TaskBundle\Entity\Category $categories
     */
    public function removeCategorie(\Acme\TaskBundle\Entity\Category $categories)
    {
        $this->categories->removeElement($categories);
    }

    /**
     * Get categories
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getCategories()
    {
        return $this->categories;
    }
}

类别实体

<?php

namespace Acme\TaskBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;

use Doctrine\ORM\Mapping as ORM;

/**
 * Category
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Category
{
    /**
     * @ORM\ManyToMany(targetEntity="Task", mappedBy="categories")
     */
    private $tasks;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Category
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->tasks = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add tasks
     *
     * @param \Acme\TaskBundle\Entity\Task $tasks
     * @return Category
     */
    public function addTask(\Acme\TaskBundle\Entity\Task $tasks)
    {
        $this->tasks[] = $tasks;

        return $this;
    }

    /**
     * Remove tasks
     *
     * @param \Acme\TaskBundle\Entity\Task $tasks
     */
    public function removeTask(\Acme\TaskBundle\Entity\Task $tasks)
    {
        $this->tasks->removeElement($tasks);
    }

    /**
     * Get tasks
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getTasks()
    {
        return $this->tasks;
    }
}

两种表格都是使用doctrine:generate:form命令自动生成的。我更改了 TaskType 表单以包含以下类别:

任务类型表单

<?php

namespace Acme\TaskBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class TaskType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('categories', new CategoryType())
        ;
    }

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

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

现在,当我转到任务的创建页面时,出现此错误:

表单的视图数据应该是 Acme\TaskBundle\Entity\Category 类的一个实例,但它是 Doctrine\Common\Collections\ArrayCollection 类的一个实例。您可以通过将“data_class”选项设置为 null 或添加将类 Doctrine\Common\Collections\ArrayCollection 的实例转换为 Acme\TaskBundle\Entity\Category 的实例的视图转换器来避免此错误。

老实说,我不知道如何解决它,因为这似乎是一件非常简单的事情,但显然事实并非如此。有人可以帮我吗?

4

1 回答 1

2

在您Task Entity删除类别的验证。
Symfony 尝试将 ArrayCollection 验证为一个类别!(因此出现错误)

* @Assert\Type(type="Acme\TaskBundle\Entity\Category")
*/
$categories;

这不是必需的,因为它是一个集合。(验证将基于集合中的对象类型)
如果您创建了 CategoryType 表单,那么该表单应该返回Acme\TaskBundle\Entity\Category它的数据类。

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

此外,在您的 TaskType

$builder
    ->add('name')
    ->add('categories', new CategoryType()) // new CategoryType()
                                            // is not really needed here,
                                            // symfony will automatically detect
                                            // it's relation and create a new 
                                            // CategoryType if necessary.
于 2013-01-18T17:39:20.707 回答