I did some research, and after reading this and this (and all the related questions) I still can't figure which is the proper way to update a many to many relationship in Symonfy 2 Doctrine. It feels that there should be a very simple way of doing it that I still haven't found.
I have this 2 entities:
class student_main
{
/**
* @ORM\ManyToMany(targetEntity="support_log", inversedBy="student_main")
* @ORM\JoinTable(name="support_log_student")
**/
private $support_log;
and
class support_log
{
/**
* @ORM\ManyToMany(targetEntity="student_main", mappedBy="support_log")
**/
private $student;
I want to start from support_log
. In the controller, in the update action, I have something like that:
if ($editForm->isValid()) {
//add the relationship the user added
foreach($students as $student){
if(!$em->getRepository('mybundle:student_main')->hasSupportLog($entity,$student)){
$entity->addstudent_main($student);//*
}
}
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('support_log_edit', array('id' => $id)));
}
Of course, as doctrine Documentation says, I changed that function (addstudent_main) accordingly:
public function addstudent_main(student_main $student)
{
$student->addsupport_log($this); // the important addition
$this->student[] = $student;
}
This works fine, my question is more about deleting the relationship. In the form there is a multiselect, and the user might select some students that are already related and some that don't. It feels that there should be an automatic way of doing that, but instead I had to do lots of code.
In the controller, just slightly above the code I wrote before, I put that:
//delete all old relationship
foreach($idsldstudents as $idst){ //I take Id's because the doctrine collection is updating always..
$stu=$em->getRepository('MyBundle:student_main')->find($idst);
$stu->deletesupport_log($entity);//I had to create that method (in the entity, I do "$this->support_log->removeElement($support_log)")
$em->persist($stu);
$em->flush();
}
I delete all the relationships of the entity in question (of course, taking in care that is a bidirectional relationship, so it has to be deleted first in the other side), and then the ones that the user selected will be added.
There are other ways of doing that, but I haven't found any simple one. In all of them I have the same problems:
- I need to check all the time if the relationship exists or not
- I need to get the old relationships (which is difficult) and compare to the new ones that the user indicated, and delete or create accordingly
Is there a way of doing that that takes care of these 2 problems automatically? (I have a strong feeling that there must be - maybe with a better declaration of the relationship? - that's why I am asking).
Thanks in advance
Edit: My form hasn't anything special, I think I didn't even touch the generated code. It displays the multiselect that I want, the default of Symfony2, where you have to use ctrl key to select more than one. Here is the code:
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('student')
...
;
}
The key relies here?