Symfony2持久嵌入式

时间:2013-02-26 19:28:40

标签: php symfony doctrine-orm

我正在关注如何嵌入表单集合的official symfony cookbook article。 我尝试用多个Trucs坚持一个Machin。

这是我的代码:

Machin实体

namespace Tmp\TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Machin
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Machin
{
    /**
     * @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;

    /**
    *
    *@ORM\ManyToMany(targetEntity="Truc", cascade={"persist"})
    */ 
    protected $trucs;

    public function __construct()
    {
        $this->tags = new ArrayCollection();
    }
    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

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

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }
    public function getTrucs()
    {
        return $this->trucs;
    }

    public function setTrucs(ArrayCollection $trucs)
    {
        foreach ($trucs as $truc) {
                $truc->addMachin($this);
            }

            $this->trucs = $trucs;
    }
}

Truc实体

namespace Tmp\TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Truc
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Truc
{
    /**
     * @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 Truc
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    public function addMachin(Machin $machin)
    {
        if (!$this->machins->contains($machin)) {
        $this->machins->add($machin);
        }
    }
}

MachinType

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

class MachinType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name');

        $builder->add('trucs', 'collection', array(
            'type' => new TrucType(),
            'allow_add' => true,
            'by_reference' => false,
            'prototype' => true));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Tmp\TestBundle\Entity\Machin',
        ));
    }

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

TrucType

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

class TrucType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name');

    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Tmp\TestBundle\Entity\Truc',
        ));
    }
    public function getDefaultOptions(array $options)
    {
    return array(
    'data_class' => 'Tmp\TestBundle\Entity\Truc',
    );
}

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

表单(我不发布javascript部分)

{%extends“:: layout.html.twig”%}

{% block content %}

<form  method="POST" {{ form_enctype(form) }}>
    {# affiche l'unique champ de la tâche : description #}
    {{ form_row(form.name) }}

    <ul class="trucs" data-prototype="{{ form_widget(form.trucs.vars.prototype)|e }}">
        {# itère sur chaque truc existant et affiche son unique champ : name #}
        {% for truc in form.trucs %}
            <li>{{ form_row(truc.name) }}</li>
        {% endfor %}
    </ul>

    {{ form_rest(form) }}
    <input type="submit" class="btn btn-primary"/>
</form>

我的控制器

namespace Tmp\TestBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Tmp\TestBundle\Entity\Machin;
use Tmp\TestBundle\Form\Type\MachinType;


class DefaultController extends Controller
{
    public function indexAction($name)
    {
        return $this->render('TmpTestBundle:Default:index.html.twig', array('name' => $name));
    }
    public function newAction(){
        $em = $this->getDoctrine()->getManager();
        $machin = new Machin();
        $form = $this->createForm(new MachinType(),$machin);
        $request = $this->get('request');
        if ($request->isMethod('POST')) {

              $form->bindRequest($request);
               //if ($form->isValid()) {

                $em->persist($machin);
                $em->flush();
                 return $this->redirect($this->generateUrl('tmp_list'));
               //}
           }else{

           }
        return $this->render('TmpTestBundle:Default:new.html.twig',array('form' => $form->createView()));
    }
    public function listAction(){
        $em = $this->getDoctrine()->getManager();

        $machin = $em->getRepository("TmpTestBundle:Machin")->findAll();
        return $this->render('TmpTestBundle:Default:list.html.twig',array('machins' => $machin));
    }
}

当我尝试保留我的实体时,出现以下错误

  

捕获致命错误:传递给Tmp \ TestBundle \ Entity \ Machin :: setTrucs()的参数1必须是Doctrine \ Common \ Collections \ ArrayCollection的实例,给定数组

我不知道在哪里错过了什么,有什么帮助吗?

1 个答案:

答案 0 :(得分:2)

你可能已经复制/粘贴了很多例子 您必须将Machin构造函数更改为:

public function __construct()
{
    $this->trucs = new ArrayCollection();

    //This was wrong:
    //$this->tags = new ArrayCollection();
}

另请注意,在MachinType课程中,您不需要'prototype' => true,因为默认为此值:http://symfony.com/doc/current/reference/forms/types/collection.html#prototype