Symfony2, relation ManyToOne bidirectionnelle
Une note pour me rappeler comment il faut faire pour implémenter une relation bidirectionnelle ManyToOne, en faisant en sorte que le côté "One" puisse ajouter / supprimer / modifier à volonté le côté "Many" :)
Soient les entités suivantes :
- un Etablissement (côté "One"), ayant plusieurs numéros de téléphone, ce que je traduis par : @ORM\OneToMany(targetEntity="path\to\EtablissementTelephone", mappedBy="etablissement", cascade={"all"}) sur la variable $telephones (qui est une ArrayCollection)
- un EtablissementTelephone (côté "Many", théoriquement propriétaire de la relation), ce que je traduis par : @ORM\ManyToOne(targetEntity="path\to\Etablissement", inversedBy="telephones") sur la variable $etablissement. J'y ajoute une condition d'obligation d'existence @ORM\JoinColumn(nullable=false)
Je génère les getters et setters par php app/console doctrine:generate:entities ...
Ensuite, dans le contrôleur, j'ai le code suivant, par exemple pour l'édition d'un Etablissement :
$originalTelephones = array();
foreach($etablissement->getTelephones() as $telephone) {
$originalTelephones[] = $telephone;
}
... // Je crée l'objet formulaire que je lie à mon établissement
// Bien entendu, j'ai pris soin de créer un EtablissementType et un EtablissementTelephoneType (cf l'excellent tuto de Winzou sur OpenClassrooms)
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
foreach($originalTelephones as $telephone) {
$em->remove($telephone);
}
$telephones = $form->get('telephones')->getData();
foreach($telephones as $telephone) {
$telephone->setEtablissement($etablissement);
}
$em->persist($etablissement);
...
}
La partie avec la variable originalTelephones permet de supprimer éventuellement des entités - dans mon cas, je veux que la personne faisant les saisies puisse ajouter / modifier / supprimer à volonté.
La partie avec $form->get('telephones')->getData() permet de lier l'entité "numéro de téléphone" saisie avec l'établissement en vue de la sauvegarde.