php - Symfony2 持久化嵌入形式

标签 php symfony doctrine-orm

我正在关注 official symfony cookbook article关于如何嵌入表单集合。 我尝试让 Machin 保持多个 Truc。

这是我的代码:

机器实体

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);
        }
    }
}

机器类型

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';
    }
}

Truc类型

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 部分)

{% 扩展“::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>

还有我的 Controller

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));
    }
}

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

Catchable Fatal Error: Argument 1 passed to Tmp\TestBundle\Entity\Machin::setTrucs() must be an instance of Doctrine\Common\Collections\ArrayCollection, array given

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

最佳答案

您可能已经过多地复制/粘贴了该示例。
您必须将 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

关于php - Symfony2 持久化嵌入形式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15097604/

相关文章:

mongodb - DoctrineMongoDBBundle : Specify Read Preference to Document Manager

php - 带有 symfony 的 SOAP 网络服务

doctrine-orm - 学说 ORM HYDRATE_SCALAR 与 HYDRATE_ARRAY

php - 通过 php 将 MYSQL 数据导出到 Excel/CSV

sql语法中的php mysqli转义字符串错误

php - 使用 PHP 对象

swift - native 登录系统(ios、android)

php - 领域驱动设计 - 聚合 - EventPublisher with Doctrine

doctrine-orm - 如何使用 Doctrine Embeddables

php - WordPress 自行更改某些选项