Zurück zur Übersicht

Laravel Record mit Beziehungen duplizieren

Vor Kurzem haben wir ein Paket ersetzt, das es uns erlaubte, einen Model-Datensatz samt aller Beziehungen zu duplizieren und anschließend Änderungen am neuen Record vorzunehmen.

Schwarze Wand mit leuchtenden Steinen
Foto von Tasha Kostyuk auf Unsplash

Gesunde Codebasen müssen gepflegt werden. Dazu gehört auch, Pakete zu entfernen, die nicht mehr benötigt werden.

Vor Kurzem haben wir ein Paket ersetzt, mit dem wir einen Model-Datensatz samt aller zugehörigen Beziehungen duplizieren und am neuen Datensatz Änderungen vornehmen konnten.

Zur Einordnung: Als wir das Paket neurony/laravel-duplicate entdeckt haben, löste es für uns ein Problem in einer zeitkritischen Situation. Wir brauchten schnell eine Lösung, um Datensätze inklusive ihrer Beziehungen zu duplizieren und zu bearbeiten – und das, während wir unser veraltetes internes CRM auf eine neue, Laravel-basierte Version umgestellt haben. Die Entscheidung für das Paket war damals also ganz bewusst. Schauen wir uns nun an, wie wir das Paket durch ein paar Zeilen eigenen Code ersetzt haben.

Die Lösung

Im Request wird zunächst der gewünschte Kunde geladen und auf einen neuen Datensatz repliziert. So erhalten wir die neue ID, die wir brauchen, um die Beziehungen richtig zu verknüpfen und den neuen Record zu speichern.

Danach gehen wir alle gewünschten Beziehungen (z. B. details, address, …) als Array durch. Wenn der Original-Kunde eine dieser Beziehungen hat, wird sie ebenfalls repliziert und der foreign_key auf den neuen primary_key des duplizierten Kunden gesetzt.

Auf diese Weise spielt es keine Rolle, welcher Beziehungstyp verwendet wird – solange wir immer den gleichen Spaltennamen für den foreign_key nutzen. Das ist Voraussetzung für diese Methode.

public function duplicate(Customer $customer)
{

    $relationships = ['details', 'address', ...];

    $clone = $customer->replicate()->fill([
        // Änderungen an den $fillable-Attributen
    ]);

    $clone->save();

    foreach ($relationships as $relationship) {
        if ($customer->$relationship) {
            $cloned_relation = $customer->$relationship->replicate();
            $cloned_relation->foreign_key = $clone->primary_key;
            $cloned_relation->save();
        }
    }

    return response()->json($clone, 201);
}

Gut zu wissen

Models unterstützen sogar das „replicating“-Event – auch wenn es nicht in der offiziellen Doku steht.

Auf GitHub findet man das Event ↗.


Danke fürs Gegenlesen, @tobias_grasse.

Dieser Artikel ist zuerst auf Englisch erschienen und wurde übersetzt.

Ähnliche Beiträge

Vor Kurzem haben wir ein Paket ersetzt, das es uns erlaubte, einen Model-Datensatz samt aller Beziehungen zu duplizieren und anschließend Änderungen am neuen Record vorzunehmen.