symfony2:无法在嵌入对象中保存父ID

时间:2013-02-24 10:39:57

标签: doctrine-orm symfony-2.1

我正在尝试使用我的第一个嵌入表单(SF2.1 + Doctrine2)

实体:

<?php
namespace Chris\BabelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 */
class Needs
{
    /**
     * @ORM\GeneratedValue
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
         * @ORM\ManyToOne(targetEntity="Projects")
         * @Assert\NotBlank()
         */
    private $relatedproject;

    /**
         * @ORM\ManyToOne(targetEntity="Activities")
         * @Assert\NotBlank()
         */
    private $relatedactivity;

    /**
         * @ORM\ManyToOne(targetEntity="Jobs")
         * @Assert\NotBlank()
         */
    private $relatedjob;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank()
     */
    private $firstname;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank()
     */
    private $lastname;

    /**
         * @ORM\ManyToOne(targetEntity="Experiences")
         * @Assert\NotBlank()
         */
    private $relatedexperience;

    /**
         * @ORM\ManyToOne(targetEntity="Plants")
         * @Assert\NotBlank()
         */
    private $maintrainingplant;

    /**
         * @ORM\Column(type="date")
         * @Assert\NotBlank()
         */
    private $trainingneedstart;

    /**
         * @ORM\Column(type="date")
         * @Assert\NotBlank()
         */
    private $readytowork;

    /**
     * @var ArrayCollection $trainings
     *
     * @ORM\OneToMany(targetEntity="Trainings", mappedBy="training", cascade={"persist", "remove", "merge"})
     */
    private $trainings;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->trainings = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set firstname
     *
     * @param string $firstname
     * @return Needs
     */
    public function setFirstname($firstname)
    {
        $this->firstname = $firstname;

        return $this;
    }

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

    /**
     * Set lastname
     *
     * @param string $lastname
     * @return Needs
     */
    public function setLastname($lastname)
    {
        $this->lastname = $lastname;

        return $this;
    }

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

    /**
     * Set trainingneedstart
     *
     * @param \DateTime $trainingneedstart
     * @return Needs
     */
    public function setTrainingneedstart($trainingneedstart)
    {
        $this->trainingneedstart = $trainingneedstart;

        return $this;
    }

    /**
     * Get trainingneedstart
     *
     * @return \DateTime 
     */
    public function getTrainingneedstart()
    {
        return $this->trainingneedstart;
    }

    /**
     * Set readytowork
     *
     * @param \DateTime $readytowork
     * @return Needs
     */
    public function setReadytowork($readytowork)
    {
        $this->readytowork = $readytowork;

        return $this;
    }

    /**
     * Get readytowork
     *
     * @return \DateTime 
     */
    public function getReadytowork()
    {
        return $this->readytowork;
    }

    /**
     * Set relatedproject
     *
     * @param \Chris\BabelBundle\Entity\Projects $relatedproject
     * @return Needs
     */
    public function setRelatedproject(\Chris\BabelBundle\Entity\Projects $relatedproject = null)
    {
        $this->relatedproject = $relatedproject;

        return $this;
    }

    /**
     * Get relatedproject
     *
     * @return \Chris\BabelBundle\Entity\Projects 
     */
    public function getRelatedproject()
    {
        return $this->relatedproject;
    }

    /**
     * Set relatedactivity
     *
     * @param \Chris\BabelBundle\Entity\Activities $relatedactivity
     * @return Needs
     */
    public function setRelatedactivity(\Chris\BabelBundle\Entity\Activities $relatedactivity = null)
    {
        $this->relatedactivity = $relatedactivity;

        return $this;
    }

    /**
     * Get relatedactivity
     *
     * @return \Chris\BabelBundle\Entity\Activities 
     */
    public function getRelatedactivity()
    {
        return $this->relatedactivity;
    }

    /**
     * Set relatedjob
     *
     * @param \Chris\BabelBundle\Entity\Jobs $relatedjob
     * @return Needs
     */
    public function setRelatedjob(\Chris\BabelBundle\Entity\Jobs $relatedjob = null)
    {
        $this->relatedjob = $relatedjob;

        return $this;
    }

    /**
     * Get relatedjob
     *
     * @return \Chris\BabelBundle\Entity\Jobs 
     */
    public function getRelatedjob()
    {
        return $this->relatedjob;
    }

    /**
     * Set relatedexperience
     *
     * @param \Chris\BabelBundle\Entity\Experiences $relatedexperience
     * @return Needs
     */
    public function setRelatedexperience(\Chris\BabelBundle\Entity\Experiences $relatedexperience = null)
    {
        $this->relatedexperience = $relatedexperience;

        return $this;
    }

    /**
     * Get relatedexperience
     *
     * @return \Chris\BabelBundle\Entity\Experiences 
     */
    public function getRelatedexperience()
    {
        return $this->relatedexperience;
    }

    /**
     * Set maintrainingplant
     *
     * @param \Chris\BabelBundle\Entity\Plants $maintrainingplant
     * @return Needs
     */
    public function setMaintrainingplant(\Chris\BabelBundle\Entity\Plants $maintrainingplant = null)
    {
        $this->maintrainingplant = $maintrainingplant;

        return $this;
    }

    /**
     * Get maintrainingplant
     *
     * @return \Chris\BabelBundle\Entity\Plants 
     */
    public function getMaintrainingplant()
    {
        return $this->maintrainingplant;
    }

    /**
     * Add trainings
     *
     * @param \Chris\BabelBundle\Entity\Trainings $trainings
     * @return Needs
     */
    public function addTraining(\Chris\BabelBundle\Entity\Trainings $trainings)
    {
        $this->trainings[] = $trainings;

        return $this;
    }

    /**
     * Remove trainings
     *
     * @param \Chris\BabelBundle\Entity\Trainings $trainings
     */
    public function removeTraining(\Chris\BabelBundle\Entity\Trainings $trainings)
    {
        $this->trainings->removeElement($trainings);
    }

    /**
     * Get trainings
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getTrainings()
    {
        return $this->trainings;
    }
    public function __toString() {return $this->getFirstname();}
}



<?php
namespace Chris\BabelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
 * @ORM\Entity
 */
class Trainings
{
    /**
     * @ORM\GeneratedValue
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
         * @ORM\ManyToOne(targetEntity="Plants")
         * @Assert\NotBlank()
         */
    private $trainingplant;

    /**
         * @ORM\Column(type="date")
         * @Assert\NotBlank()
         */
    private $trainingstart;

    /**
         * @ORM\Column(type="date")
         * @Assert\NotBlank()
         */
    private $trainingend;

    /**
     * @var Needs $trainings
     *
     * @ORM\ManyToOne(targetEntity="Needs", inversedBy="trainings", cascade={"persist", "remove", "merge"})
     * @ORM\JoinColumns({
     *  @ORM\JoinColumn(name="Needs_id", referencedColumnName="id")
     * })
     */
    private $training;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set trainingstart
     *
     * @param \DateTime $trainingstart
     * @return Trainings
     */
    public function setTrainingstart($trainingstart)
    {
        $this->trainingstart = $trainingstart;

        return $this;
    }

    /**
     * Get trainingstart
     *
     * @return \DateTime 
     */
    public function getTrainingstart()
    {
        return $this->trainingstart;
    }

    /**
     * Set trainingend
     *
     * @param \DateTime $trainingend
     * @return Trainings
     */
    public function setTrainingend($trainingend)
    {
        $this->trainingend = $trainingend;

        return $this;
    }

    /**
     * Get trainingend
     *
     * @return \DateTime 
     */
    public function getTrainingend()
    {
        return $this->trainingend;
    }

    /**
     * Set trainingplant
     *
     * @param \Chris\BabelBundle\Entity\Plants $trainingplant
     * @return Trainings
     */
    public function setTrainingplant(\Chris\BabelBundle\Entity\Plants $trainingplant = null)
    {
        $this->trainingplant = $trainingplant;

        return $this;
    }

    /**
     * Get trainingplant
     *
     * @return \Chris\BabelBundle\Entity\Plants 
     */
    public function getTrainingplant()
    {
        return $this->trainingplant;
    }

    /**
     * Set training
     *
     * @param \Chris\BabelBundle\Entity\Needs $training
     * @return Trainings
     */
    public function setTraining(\Chris\BabelBundle\Entity\Needs $training = null)
    {
        $this->training = $training;
        return $this;
    }

    /**
     * Get training
     *
     * @return \Chris\BabelBundle\Entity\Needs 
     */
    public function getTraining()
    {
        return $this->training;
    }
}

2控制器:

<?php

namespace Chris\BabelBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use Chris\BabelBundle\Entity\Needs;
use Chris\BabelBundle\Form\NeedsType;

/**
 * Needs controller.
 *
 */
class NeedsController extends Controller
{
    /**
     * Lists all Needs entities.
     *
     */
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();

        $entities = $em->getRepository('ChrisBabelBundle:Needs')->findAll();

        return $this->render('ChrisBabelBundle:Needs:index.html.twig', array(
            'entities' => $entities,
        ));
    }

    /**
     * Finds and displays a Needs entity.
     *
     */
    public function showAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ChrisBabelBundle:Needs')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Needs entity.');
        }

        return $this->render('ChrisBabelBundle:Needs:show.html.twig', array(
            'entity'      => $entity,        ));
    }

    /**
     * Displays a form to create a new Needs entity.
     *
     */
    public function newAction()
    {
        $entity = new Needs();
        $form   = $this->createForm(new NeedsType(), $entity);

        return $this->render('ChrisBabelBundle:Needs:new.html.twig', array(
            'entity' => $entity,
            'form'   => $form->createView(),
        ));
    }

    /**
     * Creates a new Needs entity.
     *
     */
    public function createAction(Request $request)
    {
        $entity  = new Needs();

        $form = $this->createForm(new NeedsType(), $entity);
        $form->bind($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($entity);
            $em->flush();

            return $this->redirect($this->generateUrl('needs_show', array('id' => $entity->getId())));
        }

        return $this->render('ChrisBabelBundle:Needs:new.html.twig', array(
            'entity' => $entity,
            'form'   => $form->createView(),
        ));
    }

    /**
     * Displays a form to edit an existing Needs entity.
     *
     */
    public function editAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ChrisBabelBundle:Needs')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Needs entity.');
        }

        $editForm = $this->createForm(new NeedsType(), $entity);

        return $this->render('ChrisBabelBundle:Needs:edit.html.twig', array(
            'entity'      => $entity,
            'edit_form'   => $editForm->createView(),
        ));
    }

    /**
     * Edits an existing Needs entity.
     *
     */
    public function updateAction(Request $request, $id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ChrisBabelBundle:Needs')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Needs entity.');
        }

        $editForm = $this->createForm(new NeedsType(), $entity);
        $editForm->bind($request);

        if ($editForm->isValid()) {
            $em->persist($entity);
            $em->flush();

            return $this->redirect($this->generateUrl('needs_edit', array('id' => $id)));
        }

        return $this->render('ChrisBabelBundle:Needs:edit.html.twig', array(
            'entity'      => $entity,
            'edit_form'   => $editForm->createView(),
        ));
    }

    /**
     * Deletes a Needs entity.
     *
     */
    public function deleteAction($id)
    {
        $em = $this->container->get('doctrine')->getEntityManager();
        $metier = $em->find('ChrisBabelBundle:Needs', $id);
        if (!$metier)
        {
            throw new NotFoundHttpException("Need not found");
        }
        $em->remove($metier); $em->flush();
        return $this->redirect($this->generateUrl('needs'));
    }
}






<?php

namespace Chris\BabelBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use Chris\BabelBundle\Entity\Trainings;
use Chris\BabelBundle\Form\TrainingsType;

/**
 * Trainings controller.
 *
 */
class TrainingsController extends Controller
{
    /**
     * Lists all Trainings entities.
     *
     */
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();

        $entities = $em->getRepository('ChrisBabelBundle:Trainings')->findAll();

        return $this->render('ChrisBabelBundle:Trainings:index.html.twig', array(
            'entities' => $entities,
        ));
    }

    /**
     * Finds and displays a Trainings entity.
     *
     */
    public function showAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Trainings entity.');
        }

        $deleteForm = $this->createDeleteForm($id);

        return $this->render('ChrisBabelBundle:Trainings:show.html.twig', array(
            'entity'      => $entity,
            'delete_form' => $deleteForm->createView(),        ));
    }

    /**
     * Displays a form to create a new Trainings entity.
     *
     */
    public function newAction()
    {
        $entity = new Trainings();
        $form   = $this->createForm(new TrainingsType(), $entity);

        return $this->render('ChrisBabelBundle:Trainings:new.html.twig', array(
            'entity' => $entity,
            'form'   => $form->createView(),
        ));
    }

    /**
     * Creates a new Trainings entity.
     *
     */
    public function createAction(Request $request)
    {
        $entity  = new Trainings();
        $form = $this->createForm(new TrainingsType(), $entity);
        $form->bind($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($entity);
            $em->flush();

            return $this->redirect($this->generateUrl('trainings_show', array('id' => $entity->getId())));
        }

        return $this->render('ChrisBabelBundle:Trainings:new.html.twig', array(
            'entity' => $entity,
            'form'   => $form->createView(),
        ));
    }

    /**
     * Displays a form to edit an existing Trainings entity.
     *
     */
    public function editAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Trainings entity.');
        }

        $editForm = $this->createForm(new TrainingsType(), $entity);
        $deleteForm = $this->createDeleteForm($id);

        return $this->render('ChrisBabelBundle:Trainings:edit.html.twig', array(
            'entity'      => $entity,
            'edit_form'   => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
     * Edits an existing Trainings entity.
     *
     */
    public function updateAction(Request $request, $id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Trainings entity.');
        }

        $deleteForm = $this->createDeleteForm($id);
        $editForm = $this->createForm(new TrainingsType(), $entity);
        $editForm->bind($request);

        if ($editForm->isValid()) {
            $em->persist($entity);
            $em->flush();

            return $this->redirect($this->generateUrl('trainings_edit', array('id' => $id)));
        }

        return $this->render('ChrisBabelBundle:Trainings:edit.html.twig', array(
            'entity'      => $entity,
            'edit_form'   => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
     * Deletes a Trainings entity.
     *
     */
    public function deleteAction(Request $request, $id)
    {
        $form = $this->createDeleteForm($id);
        $form->bind($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);

            if (!$entity) {
                throw $this->createNotFoundException('Unable to find Trainings entity.');
            }

            $em->remove($entity);
            $em->flush();
        }

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

    private function createDeleteForm($id)
    {
        return $this->createFormBuilder(array('id' => $id))
            ->add('id', 'hidden')
            ->getForm()
        ;
    }
}

最后是表格:

<?php

namespace Chris\BabelBundle\Form;

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

class NeedsType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('firstname')
            ->add('lastname')
            ->add('trainingneedstart')
            ->add('readytowork')
            ->add('relatedproject')
            ->add('relatedactivity')
            ->add('relatedjob')
            ->add('relatedexperience')
            ->add('maintrainingplant')
// Ajout du formulaire imbriqué des trainings en collection
            ->add('trainings', 'collection', array('type' => new TrainingsType(),
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
                ))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Chris\BabelBundle\Entity\Needs'
        ));
    }

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



<?php

namespace Chris\BabelBundle\Form;

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

class TrainingsType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('trainingstart')
            ->add('trainingend')
            ->add('trainingplant')
            ->add('training')
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Chris\BabelBundle\Entity\Trainings'
        ));
    }

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

除了保存的培训不包含数据库中的需求ID之外,其中大部分都有效,因此,在编辑需求时,我无法检索到多次培训。

1 个答案:

答案 0 :(得分:4)

最后,我在法国IRC的帮助下找到了解决方案:)

我只需像这样修改Needs实体:

/**
     * Add trainings
     *
     * @param \Chris\BabelBundle\Entity\Trainings $trainings
     * @return Needs
     */
    public function addTraining(\Chris\BabelBundle\Entity\Trainings $trainings)
    {
        $this->trainings[] = $trainings;

        $trainings->setTraining($this);

        return $this;
    }