我正在关注如何嵌入表单集合的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的实例,给定数组
我不知道在哪里错过了什么,有什么帮助吗?
答案 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