Come eliminare tutte le righe in una tabella usando Eloquent?


135

La mia ipotesi era di usare la sintassi seguente:

MyModel::all()->delete();

Ma quello non ha funzionato. Sono sicuro che è super semplice, ma ho cercato la documentazione sull'argomento e non riesco a trovarla!

Risposte:


279

La ragione per cui MyModel::all()->delete()non funziona è perché in all()realtà attiva la query e restituisce una raccolta di oggetti Eloquent.

Puoi usare il metodo troncato, questo funziona per Laravel 4 e 5:

MyModel::truncate();

Ciò elimina tutte le righe dalla tabella senza registrare le singole eliminazioni di riga.


1
Ho aggiunto una soluzione Laravel 3 alla mia domanda, per i futuri lettori.
Pete,

39
Bello. Funziona anche su Laravel 5 se qualcun altro si trova qui nel 2016.
samiles

14
Nota: truncate () ripristina anche qualsiasi contatore AUTO_INCREMENT (nota anche che non puoi troncare le tabelle che hanno vincoli di chiave esterna.)
William Turrell,

10
Cordiali saluti: Turncate non attiverà eventi di eliminazione.
Fusion

1
Se vuoi davvero usarlo MyModel::all()->delete(), usaforeach (MyModel::all() as $e) { $e->delete() }
Ema4rl il

70

Laravel 5.2+ soluzione.

Model::getQuery()->delete();

Basta prendere il costruttore sottostante con il nome della tabella e fare qualunque cosa. Non potrebbe essere più ordinato di così.

Laravel 5.6 soluzione

\App\Model::query()->delete();

9
Nel caso in cui qualcun altro fosse confuso sul perché funzioni, la classe Model inoltra i metodi al Builder tramite il metodo magico __call qui . Poiché la classe del modello stesso ha un metodo di eliminazione, la chiamata di Model :: delete () chiama il metodo Model, quando si desidera veramente il metodo Builder. Quindi, per ottenere esplicitamente il builder, puoi usare getQuery ().
KevinAlbs

Questo non cancella anche le tabelle correlate se lo desideri.
Terje Nesthus,


Modello :: whereNotNull ( 'id') -> delete (); - eseguirà l'eliminazione soft quando l'eliminazione soft è attivata
shalini

61

Puoi Model::truncate()disabilitare se disabiliti foreign_key_checks(suppongo che tu usi MySQL).

DB::statement("SET foreign_key_checks=0");
Model::truncate();
DB::statement("SET foreign_key_checks=1");

2
In Laravel 4, usi DB :: unprepared ()
swdev

puoi anche usare Schema :: disableForeignKeyConstraints (); & Schema :: enableForeignKeyConstraints ();
Eleazar Resendez,

33

Ho visto entrambi i metodi usati nei file seme.

// Uncomment the below to wipe the table clean before populating

DB::table('table_name')->truncate();

//or

DB::table('table_name')->delete();

Anche se non è possibile utilizzare il primo se si desidera impostare chiavi esterne .

Impossibile troncare una tabella a cui fa riferimento un vincolo di chiave esterna

Quindi potrebbe essere una buona idea usare il secondo.


2
deleteovviamente non è lo stesso di truncatese.
Joel Mellon,

2
@sudopeople Sarebbe davvero utile indicare la differenza. Potrei anche aggiungerlo alla mia risposta .
giannis christofakis,

4
TRUNCATE non può essere utilizzato in una transazione, poiché non è interessato da ROLLBACK. In tal caso, ciò può essere ottenuto con (new MyModel) -> newQuery () -> delete ().
Hammurabi,

12

C'è un modo indiretto:

myModel:where('anyColumnName', 'like', '%%')->delete();

Esempio:

User:where('id', 'like' '%%')->delete();

Informazioni sul generatore di query Laravel: https://laravel.com/docs/5.4/queries


1
@aschipfl non ha molto da spiegare in realtà. Il codice esegue l'SQL DELETE FROM users WHERE id LIKE '%%'che corrisponde a tutte le righe della tabella, eliminando così tutto.
Hkan,

Questo mi ha portato sulla mia strada. Ho finito per fare un pluck () su un altro modello per ottenere una matrice degli ID di cui avevo bisogno, quindi ho usato quella matrice per eliminare tutti i record dal mio modello usando il whereInmetodo: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC,

9

Volevo aggiungere un'altra opzione per chi arriva a questa discussione tramite Google. Avevo bisogno di farlo, ma volevo mantenere il mio valore di auto-incremento che si truncate()ripristina. Inoltre, non volevo usare DB::nulla perché volevo operare direttamente dall'oggetto modello. Quindi, sono andato con questo:

Model::whereNotNull('id')->delete();

Ovviamente la colonna dovrà effettivamente esistere, ma in un modello Eloquent standard pronto all'uso, la idcolonna esiste e non è mai nulla. Non so se questa sia la scelta migliore, ma funziona per i miei scopi.


Model::delete();realizzerà la stessa cosa.
Leng,

5
Purtroppo Model::delete()genera un'eccezione Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically, almeno in Laravel 5.0.
Dave James Miller,

6

Non sono stato in grado di utilizzare Model::truncate()come sarebbe l'errore:

SQLSTATE [42000]: errore di sintassi o violazione di accesso: 1701 Impossibile troncare una tabella a cui fa riferimento un vincolo di chiave esterna

E purtroppo Model::delete()non funziona (almeno in Laravel 5.0):

Il metodo non statico Illuminate \ Database \ Eloquent \ Model :: delete () non deve essere chiamato staticamente, presupponendo $ this da un contesto incompatibile

Ma questo funziona:

(new Model)->newQuery()->delete()

Ciò eliminerà automaticamente tutte le righe, se è stata configurata l'eliminazione soft. Per eliminare completamente tutte le righe, comprese quelle a eliminazione graduale, è possibile passare a questa:

(new Model)->newQueryWithoutScopes()->forceDelete()

4

Il modo migliore per eseguire questa operazione Laravel 3sembra essere l'uso Fluentdell'interfaccia per troncare la tabella come mostrato di seguito

DB::query("TRUNCATE TABLE mytable");

2

Puoi provare questo one-liner che conserva anche le soft-delete:

Model::whereRaw('1=1')->delete();


0

Analogamente alla risposta di Travis vignon, ho richiesto i dati dal modello eloquente e, se le condizioni erano corrette, dovevo eliminare o aggiornare il modello. Ho finito per ottenere il campo minimo e massimo restituito dalla mia query (nel caso in cui un altro campo fosse aggiunto alla tabella che soddisfacesse i miei criteri di selezione) insieme ai criteri di selezione originali per aggiornare i campi tramite una query SQL non elaborata (come al contrario di una query eloquente per oggetto nella raccolta).

So che l'uso di SQL raw viola la meravigliosa filosofia del codice Laravels, ma sarebbe difficile rispondere a centinaia di query al posto di una.


0

Può fare un loop troppo ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}

Tecnicamente sì ... ma IMO sembra un po 'inutile poiché ci sono migliori opzioni per query singole.
Pete,

@Pete lo so .. altri hanno già dato le loro risposte ... stavo cercando di rispondere all'altro possibile metodo da fare ..
Sam Solomon,

1
Questo in realtà funziona per me, poiché ho intenzione di archiviare i modelli nella raccolta in base a regole specifiche, ma anche di cancellarli da quella tabella attiva quotidianamente.
James Perih,

-1

Soluzione che funziona con Lumen 5.5 con vincoli di chiavi esterne:

$categories = MusicCategory::all();
foreach($categories as $category)
{
$category->delete();

}
return response()->json(['error' => false]);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.