2015-07-16 24 views
15

Sto avendo offerte e servizi tabella.Laravel 5: cascata soft delete

Il/i servizio/i è figlio di un'offerta. Finora ho stabilito le funzionalità per la cancellazione soft di un'offerta. Come dovrei eliminare anche i servizi aggiunti? Qui è il mio codice:

migrazione Offerte

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

servizi di migrazione

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'); 
}); 

modello di offerta

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

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

Service Model

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

metodo Delete

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

Grazie per tutto l'aiuto.

risposta

23

ho messo questo codice nel modello di offerta:

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

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

E ha aggiunto manca

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

nel modello di servizio.

+2

ma questa soluzione non funziona se i servizi stessi hanno FK ... L'eliminazione non viene attivata nel modello figlio –

+0

Ho sbattuto la testa contro il muro sul motivo per cui questo non ha funzionato per me .. Scoprì che era perché non chiama i metodi 'delete' e' deleted' quando effettua direttamente una chiamata alla query. Ecco alcuni altri dettagli ed esempi su come farlo funzionare: https: // github.it/laravel/framework/issues/2536 # issuecomment-74557441 –

4

Per questo è necessario utilizzare Eloquent events.

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

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

Grazie per il vostro ef forte. Ho provato a mettere questo codice nel mio metodo di cancellazione in fondo, ma i servizi persistono ancora nel database. Devo scrivere qualcosa da solo? –

+0

Qualcuno con una risposta? Grazie. –

1

Si può fare così.

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

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

È necessario prima cancellare/ripristinare i record figli (servizi) prima di eliminare/ripristinare il genitore (offerta). Non riuscendo a fare ciò, si innesca l'errore di integrità MySql referenziale.

+2

Non può attivare un errore di integrità perché i record sono semplicemente eliminati. Tuttavia, ripristineresti il ​​genitore prima di ripristinare i bambini. Quindi usa 'self :: restored'. – halloei

1

Se si desidera ottenere a cascata softDeletes nei modelli eloquenti Consiglio vivamente l'utilizzo di questa libreria iatstuti/laravel-cascade-soft-deletes

Compositore

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

esempio rapida (quello fornito nel campione introduttiva)

<?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); 
    } 
}