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 フォームを変更して、カテゴリを含めました。

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 を 1 つのカテゴリとして検証しようとします!(したがってエラー)

* @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 に答える