0

I have problem with the array collection.

If i don't use "$livraison->setChoix($livraison->getChoix());" in form valid, the item is doesn't save in relation. And with this, the item in collection as duplicate in any save.

i have 2 entity, "Livraison" and "LivraisonChoix"

Livraison is in relation OneToMany with LivraisonChoix LivraisonChoix is in relation ManyToOne with Livraison

this is the Livraison :

...
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

class Livraison
{

...

    /**
     * @ORM\OneToMany(targetEntity="\YOU\CommercantBundle\Entity\LivraisonChoix", mappedBy="livraison", cascade={"all"})
     **/
    private $choix;

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


    public function addChoix(\YOU\CommercantBundle\Entity\LivraisonChoix $choix)
    {
        $choix->setLivraison($this);
        $this->choix[] = $choix;
    }

    public function setChoix($choix)
    {
        foreach($choix as $choi){
            $this->addChoix($choi);
        }
    }

    public function removeChoix($choix)
    {
        $this->choix->removeElement($choix);
    }

    public function getChoix()
    {
        return $this->choix;
    }

...

this is the LivraisonChoix :

use Doctrine\ORM\Mapping as ORM;

class LivraisonChoix
{

...

    /**
     * @ORM\ManyToOne(targetEntity="YOU\CommercantBundle\Entity\Livraison", inversedBy="choix")
     **/
    private $livraison;

...


    public function setLivraison($livraison)
    {
        $this->livraison = $livraison;

        return $this;
    }

    public function getLivraison()
    {
        return $this->livraison;
    }

...

this is the form builder :

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name')
        ->add('choix','collection',array(
                        'type'=>new LivraisonChoixType(),
                        'allow_add' => true,
                        'allow_delete' => true,
        ))
    ;
}

And this is the controller :

        $livraison = new Livraison();

        $form = $this->createForm(new LivraisonType(), $livraison);

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

            if ($form->isValid()) {

                $livraison->setAccount($customer);
                $livraison->setChoix($livraison->getChoix());
                $em->persist($livraison);
                $em->flush();

                return $this->redirect($this->generateUrl('you_commercant_livraison_editer',array('id'=>$livraison->getId())));

            }
        }
Paul T.
  • 577
  • 1
  • 9
  • 21

1 Answers1

0

You forgot an important thing, get the new "livraison" ($form->getData()) after form submitting :

if ($form->isValid()) {

    $livraison = $form->getData(); // You forgot to get the new / edited "livraison"

    $livraison->setAccount($customer);
    $em->persist($livraison);
    $em->flush();

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

EDIT:

I think you should add 'by_reference' set to false in your form field, this will call the addChoix() method ! Check this cookbook (at the end of this part). The detail of by_reference here.

$builder->add('choix', 'collection', array(
    // ...
    'by_reference' => false,
));
Sybio
  • 8,565
  • 3
  • 44
  • 53
  • thx. But the problem is already here with this. The form data is save, but the value of "livraison", in "LivraisonChoix" is "null" The "addChoix" method in "Livraison" aren't used in the save :/ – Paul T. Jun 21 '13 at 15:12
  • I edit my answer, I think you need to add : 'by_reference' => false, – Sybio Jun 21 '13 at 15:23
  • Yeah ! thx ! When i remove an item in the form, the item isn't removed, do you know why ? very thx! – Paul T. Jun 21 '13 at 15:34
  • Yes it's explain in the same cookbook, : http://symfony.com/doc/current/cookbook/form/form_collections.html. You need explicitly remove choix ! To do it, loop the choix id and compare them with old choix id. Search the title "Doctrine: Ensuring the database persistence" (the grey frame at the end of the tutorial), there is the example (choix are replaced by tags) ;) Please set answer solved ! – Sybio Jun 21 '13 at 15:50