Richtige Art und Weise zu aktualisieren, bidirektionale m: N-Beziehung symfony2-Lehre
Habe ich einige der Forschung, und nach der Lektüre diese und diese (und alle dazugehörigen Fragen) ich kann immer noch nicht herausfinden, was ist die richtige Art und Weise zu aktualisieren, eine viele zu viele Beziehung in Symonfy 2 Lehre. Es fühlt, dass es eine sehr einfache Möglichkeit, es zu tun, dass ich immer noch nicht gefunden.
Habe ich diese 2 Personen:
class student_main
{
/**
* @ORM\ManyToMany(targetEntity="support_log", inversedBy="student_main")
* @ORM\JoinTable(name="support_log_student")
**/
private $support_log;
und
class support_log
{
/**
* @ORM\ManyToMany(targetEntity="student_main", mappedBy="support_log")
**/
private $student;
Beginnen möchte ich aus support_log
. Im controller in der update-Aktion, ich habe so etwas wie, dass:
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)));
}
Natürlich, wie in der Lehre Dokumentation sagt, dass ich geändert, die Funktion (addstudent_main) entsprechend:
public function addstudent_main(student_main $student)
{
$student->addsupport_log($this); //the important addition
$this->student[] = $student;
}
Dies funktioniert gut, meine Frage ist mehr über das löschen der Beziehung. In der form es ist eine Mehrfachauswahl, und der Benutzer könnte wählen Sie einige Schüler, die bereits Verwandte und einige, die nicht. Es fühlt, dass es einen automatischen Weg, das zu tun, sondern ich hatte zu tun, viele code.
In den controller, nur wenig über dem code, den ich schrieb, bevor, ich:
//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();
}
Ich lösche alle Beziehungen der Entität in Frage (natürlich, sich in der Pflege, dass ist eine bidirektionale Beziehung, so muss es zunächst gelöscht werden, die in der anderen Seite), und dann diejenigen, die der Benutzer ausgewählt wird, Hinzugefügt werden.
Gibt es andere Möglichkeiten, das zu tun, aber ich habe nicht gefunden eine einfache. In allen von Ihnen habe ich die gleichen Probleme:
- Ich brauche, um zu überprüfen, alle die Zeit, wenn die Beziehung vorhanden ist oder nicht
- Ich brauche, um die alten Beziehungen (was schwierig ist), und vergleichen Sie mit den neuen Dateien, die der Benutzer angegeben, und löschen oder erstellen Sie entsprechend
Gibt es einen Weg, das zu tun, der kümmert sich um diese 2 Probleme automatisch? (Ich habe ein starkes Gefühl, dass es sein muss - vielleicht mit einer besseren Erklärung der Beziehung? - das ist, warum ich Frage).
Vielen Dank im Voraus
Bearbeiten:
Meine form hat nichts besonderes, ich glaube, ich habe noch nicht einmal berühren, den generierten code. Es zeigt die multiselect, die ich will, die Standardeinstellung von Symfony2, wo Sie verwenden Sie Strg - Taste, um mehrere auszuwählen. Hier ist der code:
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('student')
...
;
}
Den Schlüssel setzt hier?
- Erste Idee ist die Verwendung von $student->supportLog->clear(); anstelle von loop. Aber es ist keine Antwort, es ist nur die Verbesserung. Zweite ist, dass die form verwalten können Sammlungen automatisch. Kann man den code des Formulars geben, dann bitte.
- Diese erste Idee gibt eine ziemlich wertvolle Verbesserung, es ist viel eleganter! danke! Für die form, es ist die Ebene, generiert Symfony, wusste ich noch nicht einmal berühren, denke ich, nehmen Sie einen Blick auf das Bearbeiten-bitte @DmitryKrasun
- (nur ein Hinweis, in supportlog controller: $student->supportLog->clear(); wird nicht funktionieren, weil es löscht alle Beziehungen, die der Schüler hat, und ich will einfach nur löschen einer Beziehung, mit der Unterstützung anmelden, ich bin gerade Bearbeiten (und die Schleife ist das gleiche für alle anderen Studierenden, die bereits im Zusammenhang mit diesem support melden, ich bin derzeit in Bearbeitung)
- Ich bin das fallenlassen dieser hier, da habe ich nicht eine Lösung, die symfony-spezifisch. Dies sollte klären, wie Sie zu behandeln viele zu viele auf Ebene der Entitäten: gist.github.com/3121916
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bisher (und um zu vermeiden, dass eine Frage unbeantwortet ewig), wie es aussieht, gibt es keine "einfache Möglichkeit, die ich noch nicht gefunden", das zu tun. Das wäre die Antwort auf meine Frage, nach den Kommentaren.
Aber der code verbessert werden kann und es eleganter Dank der Verbesserungen der letzten Bemerkung. Wenn auf Ebene der Entitäten, die wir haben, die: gist.github.com/3121916 (aus dem Kommentar)
Dann, den code in den controller reduziert werden kann, ein wenig:
Es ist noch nicht die "Magische" symfony-Lösung, die ich erwartet, aber bisher das beste was ich tun kann (vielleicht Gruppe dieser code innerhalb einer Funktion im repository, um zu machen es mehr elegant).
Wenn Euch bessere Ideen, ich bin ganz Ohr.
Präsentiere ich meine Lösung für alle, die suchen eine Lösung.
Ich verwende Symfony 2.5.
Meiner 'Post' - Entität hat viele-zu-viele-bidirektional.
Controller:
Ich Binde meine Person durch die folgende routing:
Meinem repository:
Form-Klasse:
Es lohnt sich zu erwähnen, dass Symfony finden bestimmten Person (Post), indem Sie nur die id-routing:
Lehre entsprechend der Dokumentation es wird nur prüfen, der besitzenden Seite eines Vereins für Veränderungen.
http://doctrine-orm.readthedocs.org/en/latest/reference/unitofwork-associations.html
Also der beste Weg ist immer der Besitz Seite Entität assotiations aktualisiert.
In diesem Fall müssen Sie entfernen und hinzufügen support_log an Schüler der Haupt-in add-und remove-Methoden
Thats alle, keine Notwendigkeit zu ändern, controller-Aktionen.
Wichtige Umsetzung in der umgekehrten Seite des Vereins!
ManyToMany Bidirektional mit indexBy Attribut der annotation fest das für mich
Schüler der Klasse annotation sollte
Support-Klasse die annotation sollte
Nun das symfony 2 Form sollte
Auf submit der form, in der Regel innerhalb des Action -
Bitte beachten Sie: ich habe noch nicht getestet mit diesem code. Ich schrieb diesen code, um die Passform Szenario in der Frage genannten.