2015-08-23 3 views
9

Ich habe Rechnungen diese Tabelle, was die folgende StrukturWie lösche ich verwandte Datensätze, wenn ein übergeordneter Datensatz in Laravel gelöscht wird?

id | name | amount | deleted_at 
2 iMac 1500 | NULL 

und Zahlungen Tabelle mit der folgenden Struktur

id | invoice_id | amount | deleted_at 
2 2   1000 | NULL 

Rechnung Modell

class Invoice extends Model { 

    use SoftDeletes; 

} 

hier ist der Code zu löschen hat die Rechnung

public function cance(Request $request,$id) 
{ 
    $record = Invoice::findOrFail($id); 
    $record->delete(); 
    return response()->json([ 
     'success' => 'OK', 
    ]); 
} 

Zahlungen Modell

class Payment extends Model { 

    use SoftDeletes; 

} 

Die softDelete auf dem Tisch Rechnung funktioniert perfekt, aber die dazugehörigen Aufzeichnungen (Zahlungen) noch exists.How ich sie softDelete mit lösche?

Antwort

10

Eloquent bietet keine automatische Löschung verwandter Objekte, daher müssen Sie selbst Code schreiben. Zum Glück ist es ziemlich einfach.

Eloquent Modelle feuern verschiedene Ereignisse in verschiedenen Phasen des Lebenszyklus des Modus - Sie können mehr darüber hier lesen: http://laravel.com/docs/5.1/eloquent#events. Was Sie brauchen, ist ein Listener, der ausgeführt wird, wenn gelöscht Ereignis ausgelöst wird - dieser Listener sollte dann alle verwandten Objekte löschen.

Sie können Modelllistener in der boot() Methode Ihres Modells registrieren. Der Listener sollte alle Zahlungen für die gelöschte Rechnung durchlaufen und sie einzeln löschen. Massenlöschung funktioniert hier nicht, da die SQL-Abfrage unter Umgehung von Modellereignissen ausgeführt wird.

Dies wird der Trick:

class MyModel extends Model { 
    protected static function boot() { 
    parent::boot(); 

    static::deleted(function ($invoice) { 
     $invoice->payments()->delete(); 
    }); 
    } 
} 
+0

Funktioniert nicht! FatalErrorException in Invoice.php Zeile 18: Kann nicht statische Methode Illuminate \ Database \ Eloquent \ Model :: Boot() nicht statisch in der Klasse App \ Models \ Rechnung – user3407278

+0

Fixed, die Funktion fehlte die statische Modifikator –

+0

Das hat sehr gut funktioniert ! Danke vielmals! Führt dies zu Leistungsproblemen, wenn beim Löschen etwa 100 Einträge angezeigt werden? – user3407278

8

Sie können eine von 2 Möglichkeiten mit diesem gehen.

Der einfachste Weg wäre Eloquents delete() Methode außer Kraft setzen und die entsprechenden Modelle auch zB:

public function delete() 
{ 
    $this->payments()->delete(); 
    return parent::delete(); 
} 

Die obige Methode sollte nur Arbeit finden, aber es scheint ein wenig schmutzig, und ich würde sagen, es ist nicht die bevorzugte Methode innerhalb der Gemeinschaft.

Der Reiniger Weg (IMO) wäre in Eloquents Ereignisse tippen z.B .:

public static function boot() 
{ 
    parent::boot(); 

    static::deleting(function($invoice) { 
     $invoice->payments()->delete(); 

    }); 
} 

Entweder (aber nicht beide) der oben genannten Methoden in Ihrem Invoice Modell gehen würde. Außerdem gehe ich davon aus, dass Ihre Beziehungen in Ihrem Modell eingerichtet sind. Ich bin mir jedoch nicht sicher, ob Sie mehrere Zahlungen für eine Rechnung zulassen. In beiden Fällen müssen Sie möglicherweise die payments() in den Beispielen zu dem ändern, was Sie in Ihrem Rechnungsmodell als Beziehung bezeichnet haben.

Hoffe, das hilft!

+0

Aufruf() auf Zahlungen Beziehung löschen direkt das Modell umgehen und die SoftDelete auf ähnliche Modelle nicht auslösen. Sie werden aus der Datenbank entfernt. Um thek-deleted zu machen, müssen Sie delete() für jedes der verwandten Modelle aufrufen. –

+0

Sie fehlen auch die return-Anweisung in Ihrer überschriebenen Methode löschen - es sollte "return elter :: delete();" tun, sonst verlieren Sie den Wert, der von delete() zurückgegeben würde, wenn Sie es nicht überschrieben hatten. –

+0

@ jedrzej.kurylo, Ich habe gerade getestet, um sicherzustellen, und JA können Sie Soft-Löschen auf eine Beziehung verwenden! –

Verwandte Themen