2015-07-16 15 views
15

Ich habe Angebote und Dienstleistungen Tabelle.Laravel 5: Kaskade weich löschen

Service (s) ist ein Kind eines Angebotes. Bisher habe ich Funktionalität zum weichen Löschen eines Angebots eingerichtet. Wie würde ich auch die angehängten Dienste löschen? Hier ist mein Code:

Migration Angebote

Schema::create('offers', function(Blueprint $table) 
{ 
    $table->increments('id')->unsigned(); 
    ...  
    $table->timestamps(); 
    $table->softDeletes(); 
}); 

Migration Services

Schema::create('services', function(Blueprint $table) 
{ 
    $table->increments('id'); 
    $table->integer('offer_id')->unsigned(); 
    ... 
    $table->timestamps(); 
    $table->softDeletes(); 
}); 

Schema::table('services', function($table) 
{ 
    $table->foreign('offer_id') 
      ->references('id') 
      ->on('offers'); 
}); 

Modell Angebot

use SoftDeletes; 
protected $dates = ['deleted_at']; 

public function services() { 
    return $this->hasMany('App\Service'); 
} 

Modell Dienst

public function offer() { 
    return $this->belongsTo('App\Offer'); 
} 

Delete-Methode

public function destroy($id) 
{ 
    $offer = Offer::find($id); 
    $offer->delete(); 
} 

Vielen Dank für all die Hilfe.

Antwort

23

Ich habe diesen Code in Angebotsmodell setzen:

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

    static::deleting(function($offer) { 
     $offer->services()->delete(); 
    }); 
} 

Und hinzugefügt

use SoftDeletes; 
protected $dates = ['deleted_at']; 

im Service-Modell fehlt.

+2

aber diese Lösung funktioniert nicht, wenn Dienste selbst FK hat ... Löschen wird nicht ausgelöst in das Kindmodell –

+0

Ich habe meinen Kopf gegen die Wand geschlagen, warum das für mich nicht funktioniert hat .. herausgefunden, es war weil Es ruft nicht die Methoden 'deleting' und' deleted' auf, wenn ein Aufruf direkt an die Abfrage gesendet wird. Hier sind einige weitere Details und Beispiele, wie es funktioniert: https: // github.com/laravel/framework/issues/2536 # issuecomment-74557441 –

4

Sie sollten hierfür Eloquent events verwenden.

Offers::deleted(function($offer) { 
    $offer->services()->delete(); 
}); 

Offers::restored(function($offer) { 
    $offer->services()->withTrashed()->restore(); 
}); 
+0

Vielen Dank für Ihre ef Fort. Ich habe versucht, diesen Code in meine Löschmethode am unteren Rand zu setzen, aber die Dienste bleiben in der Datenbank bestehen. Muss ich etwas selbst schreiben? –

+0

Jemand mit einer Antwort? Vielen Dank. –

1

Sie können so tun.

self::deleting(function($offer) { 
    $offer->services()->delete(); 
}); 

self::restoring(function ($offer) { 
    $offer->services()->restore(); 
}); 

Sie sollten zuerst die Kinder Aufzeichnungen (Dienstleistungen) vor dem Löschen/Wiederherstellen des Mutterunternehmens (Angebot) löschen/wiederherstellen. Wird dies nicht durchgeführt, wird der MySql-Fehler der referenziellen Integrität ausgelöst.

+2

Es kann keinen Integritätsfehler auslösen, weil die Datensätze nur weich gelöscht werden. Sie würden jedoch das übergeordnete Element wiederherstellen, bevor Sie die untergeordneten Elemente wiederherstellen. Also benutze 'self :: restaured'. – halloei

1

Wenn Sie softDeletes in Ihrem Eloquent Models bekommen Kaskadierung I iatstuti/laravel-cascade-soft-deletes

Komponist

// get it with composer. 
$ composer require iatstuti/laravel-cascade-soft-deletes="1.0.*" 

Schnell Beispiel (die in der Begleit-Probe zur Verfügung gestellt eins) mit dieser Bibliothek sehr empfehlen

<?php 

namespace App; 

use App\Comment; 
use Iatstuti\Database\Support\CascadeSoftDeletes; 
use Illuminate\Database\Eloquent\Model; 
use Illuminate\Database\Eloquent\SoftDeletes; 

class Post extends Model 
{ 
    use SoftDeletes, CascadeSoftDeletes; 

    protected $cascadeDeletes = ['comments']; 

    protected $dates = ['deleted_at']; 

    public function comments() 
    { 
     return $this->hasMany(Comment::class); 
    } 
}