形式上的双向关系

时间:2014-04-10 08:27:07

标签: symfony doctrine

我很难保存包含OneToMany双向关系集合的表单。

我收到以下错误:

An exception occurred while executing 'INSERT INTO fieldsgroup (title, colloque_id) VALUES (?, ?)' with params ["groupe 1", null]:

以下是分析器给我的查询:     开始交易;

INSERT INTO colloque (title)
VALUES
  ('titre du colloque');

INSERT INTO fieldsgroup (title, colloque_id)
VALUES
  ('titre de mon groupe de champs', null)

ROLLBACK    

我的控制器:

public function createColloqueAction()
{

  $colloque = new Colloque();   
  $form = $this->createForm(new ColloqueType, $colloque);   

  $request = $this->get('request');   
  if ($request->getMethod() == 'POST'){   
    $form->bind($request);

    if ($form->isValid()) {

      $this->get('session')->getFlashBag()->add('notice', 'Colloque correctement enregistré');

      $em = $this->getDoctrine()->getManager();
      $em->persist($colloque);
      $em->flush();

      return $this->redirect($this->generateUrl('ptolemee_admin_homepage'));
    }   

  }       

  return $this->render('PtolemeeAdminBundle:Admin:createColloque.html.twig',array(
    'form'    =>   $form->createView()                                         
  ));
}

我的" Colloque"实体:

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

    /**
     * @ORM\OneToMany(targetEntity="Ptolemee\ColloqueBundle\Entity\FieldsGroup", mappedBy="colloque", cascade={"persist"})
     */
    private $fieldsGroups; 

    public function __construct()
    {
        $this->fieldsGroups = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add fieldsGroups
     *
     * @param \Ptolemee\ColloqueBundle\Entity\FieldsGroup $fieldsGroups
     * @return Colloque
     */
    public function addFieldsGroup(\Ptolemee\ColloqueBundle\Entity\FieldsGroup $fieldsGroups)
    {
        $this->fieldsGroups[] = $fieldsGroups;
        $fieldsGroups->setColloque($this);
        return $this;
    }

    /**
     * Remove fieldsGroups
     *
     * @param \Ptolemee\ColloqueBundle\Entity\FieldsGroup $fieldsGroups
     */
    public function removeFieldsGroup(\Ptolemee\ColloqueBundle\Entity\FieldsGroup $fieldsGroups)
    {
        $this->fieldsGroups->removeElement($fieldsGroups);
    }

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

它的形式,ColloqueType:

class ColloqueType extends AbstractType
{
        /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title',              'text')
            ->add('date',               'datetime')
            ->add('successMessage',     'textarea')
            ->add('fieldsGroups',       'collection',   array(  'type'        =>      new FieldsGroupType(),
                                                                'allow_add'   =>      true,
                                                                'allow_delete'   =>   true))
        ;
    }
}

我的类FieldsGroup

class FieldsGroup
{

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

    /**                                                                                  
     * @ORM\ManyToOne(targetEntity="Ptolemee\ColloqueBundle\Entity\Colloque", inversedBy="fieldsGroups")
     * @ORM\JoinColumn(nullable=false)
     */
    private $colloque;

    /**
     * Set colloque
     *
     * @param \Ptolemee\ColloqueBundle\Entity\Colloque $colloque
     * @return FieldsGroup
     */
    public function setColloque(\Ptolemee\ColloqueBundle\Entity\Colloque $colloque)
    {
        $this->colloque = $colloque;

        return $this;
    }

    /**
     * Get colloque
     *
     * @return \Ptolemee\ColloqueBundle\Entity\Colloque
     */
    public function getColloque()
    {
        return $this->colloque;
    }

}

其形式为FieldsGroupType:

class FieldsGroupType extends AbstractType
{
        /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title',      'text')
            /*->add('fields',     'collection',   array('type'        =>      new FieldType(),
                                                      'allow_add'   =>      true,
                                                      'allow_delete'   =>      true))*/
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Ptolemee\ColloqueBundle\Entity\FieldsGroup'
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'ptolemee_colloquebundle_fieldsgroup';
    }
}

我知道这应该在没有更多perist()或其他任何事情的情况下正常工作...... 任何帮助都将受到高度赞赏,我一直在努力工作数小时而没有找到正确的方法....

非常感谢!

2 个答案:

答案 0 :(得分:0)

只需将setFieldsGroup(ArrayCollection)添加到您的实体

即可
     public function addFieldsGroup(\Ptolemee\ColloqueBundle\Entity\FieldsGroup $fieldsGroups)
        {
           $this->fieldsGroups[] = $fieldsGroups;
           $fieldsGroups->setColloque($this);
           return $this;
        }

    public function setFieldsGroup(ArrayCollection $fieldsGroups)
       {
           foreach ($fieldsGroups as $fieldsGroup) {
               $fieldsGroup->setColloque($this);
           }
           $this->fieldsGroups = $fieldsGroups;
       }

答案 1 :(得分:0)

添加setFieldsGroup(ArrayCollection)正在运行,但这是一个技巧。

只需将, cascade={"persist"}添加到ManyToOne字段

即可
/**                                                                                  
 * @ORM\ManyToOne(targetEntity="Ptolemee\ColloqueBundle\Entity\Colloque", inversedBy="fieldsGroups", cascade={"persist"})
 * @ORM\JoinColumn(nullable=false)
 */
private $colloque;

PS1: 如果您有Symfony2.x x> = 3,则首选handleRequest()而不是$request->getMethod() == 'POST'$form->bind($request)

PS2: 您可以在需要时获得这样的请求(更优雅的方式):

public function createColloqueAction(Request $request)