Ich habe viele, viele Beziehungen aufgebaut und arbeite, um einen Artikel in den Warenkorb zu legen, den ich benutze:
$cart->items()->attach($item);
Dadurch wird der Pivot-Tabelle ein Element hinzugefügt (wie es sollte). Wenn der Benutzer jedoch erneut auf den Link klickt, um ein bereits hinzugefügtes Element hinzuzufügen, wird ein doppelter Eintrag in der Pivot-Tabelle erstellt.
Gibt es eine integrierte Möglichkeit, einen Datensatz nur dann zu einer Pivot-Tabelle hinzuzufügen, wenn noch keiner vorhanden ist?
Wenn nicht, wie kann ich die Pivot-Tabelle überprüfen, um festzustellen, ob bereits ein übereinstimmender Datensatz vorhanden ist?
attach()
ist gemischt, er kann ein Int oder eine Instanz des Modells sein;) - siehe github.com/laravel/framework/blob/master/src/Illuminate/…contains
Anweisung Überprüfen Sie, ob der Schlüssel in einem Objekt in der Auflistung vorhanden ist. Sie sollten einen Fehler in Ihrem Code haben.$cart->items()->where('foreign_key', $foreignKey)->count()
Was eigentlich auch eine zusätzliche Abfrage ausführt '^^ Aber ich muss nicht abrufen und Hydratieren Sie die gesamte Sammlung, es sei denn, ich brauche sie wirklich.exists()
Funktion sogar anstellecount()
der besten Optimierung verwenden.Sie können auch die
$model->sync(array $ids, $detaching = true)
Methode verwenden und das Trennen deaktivieren (der zweite Parameter).Update: Seit Laravel 5.3 oder 5.2.44 können Sie auch syncWithoutDetaching aufrufen:
Welches macht genau das gleiche, aber besser lesbar :)
quelle
$cart->items()->sync([1, 2, 3])
viele-zu-viele Beziehungen zu dem IDs in der gegebenen Anordnung konstruieren,1
,2
, und3
, und löscht (oder „detach“) all andere ID ist in dem Array nicht. Auf diese Weise sind nur die im Array angegebenen IDs in der Tabelle vorhanden. Brilliant @Barryvdh verwendet einen undokumentierten zweiten Parameter, um diese Trennung zu deaktivieren, sodass keine Beziehungen gelöscht werden, die nicht im angegebenen Array enthalten sind, sondern nur eindeutige IDs angehängt werden. Lesen Sie das Dokument "Synchronisierung aus Gründen der Benutzerfreundlichkeit". (Laravel 5.2)syncWithoutDetaching()
, wodurch sync () mit false als zweitem Parameter aufgerufen wird.syncWithoutDetaching()
funktioniert!Die @ alxandre Butynsky-Methode funktioniert sehr gut, verwendet jedoch zwei SQL-Abfragen.
Eine zum Überprüfen, ob der Warenkorb den Artikel enthält, und eine zum Speichern.
Um nur eine Abfrage zu verwenden, verwenden Sie Folgendes:
quelle
So gut all diese Antworten sind, weil ich sie alle ausprobiert habe, eines bleibt immer noch unbeantwortet oder wird nicht erledigt: das Problem der Aktualisierung eines zuvor aktivierten Werts (deaktiviert das Kontrollkästchen [es]). Ich habe etwas Ähnliches wie die obige Frage. Ich möchte die Funktionen von Produkten in meiner Produkt-Feature-Tabelle (der Pivot-Tabelle) aktivieren und deaktivieren. Ich bin ein Neuling und ich habe festgestellt, dass keiner der oben genannten das getan hat. Die sind beide gut, wenn Sie neue Funktionen hinzufügen, aber nicht, wenn ich vorhandene Funktionen entfernen möchte (dh deaktivieren)
Ich werde jede Erleuchtung in diesem Bereich schätzen.
oder
Sorry Leute, ich bin mir nicht sicher, ob ich die Frage löschen soll, denn nachdem ich die Antwort selbst herausgefunden habe, klingt es ein bisschen dumm. Die Antwort auf das oben Gesagte ist so einfach wie das Arbeiten mit @Barryvdh sync () wie folgt. immer mehr gelesen über:
quelle
Sie können einfach verwenden
$cart->items()->sync($items)
Ab Laravel 5.7:
quelle
Es gibt bereits einige großartige Antworten. Ich wollte diesen aber auch hier rauswerfen.
Die Antworten von @AlexandreButynski und @Barryvdh sind besser lesbar als mein Vorschlag. Diese Antwort fügt eine gewisse Effizienz hinzu.
Es ruft nur die Einträge für die aktuelle Kombination ab (eigentlich nur die ID) und hängt sie dann an, wenn sie nicht vorhanden ist. Die Synchronisierungsmethode (auch ohne Trennung) ruft alle aktuell angehängten IDs ab. Für kleinere Mengen mit kleinen Iterationen wird dies kaum ein Unterschied sein, ... Sie verstehen, worum es geht.
Wie auch immer, es ist definitiv nicht so lesbar, aber es macht den Trick.
quelle