Comment supprimer toutes les lignes d'un tableau en utilisant Eloquent?


135

Mon hypothèse était d'utiliser la syntaxe suivante:

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

Mais ça n'a pas marché. Je suis sûr que c'est super simple, mais j'ai cherché de la documentation sur le sujet et je ne peux pas la trouver!

Réponses:


279

La raison MyModel::all()->delete()ne fonctionne pas parce all()que déclenche en fait la requête et renvoie une collection d'objets Eloquent.

Vous pouvez utiliser la méthode truncate, cela fonctionne pour Laravel 4 et 5:

MyModel::truncate();

Cela supprime toutes les lignes de la table sans enregistrer les suppressions de lignes individuelles.


1
J'ai ajouté une solution Laravel 3 à ma question, pour les futurs lecteurs.
Pete

39
Agréable. Cela fonctionne aussi sur Laravel 5 si quelqu'un d'autre se google ici en 2016.
samiles

14
Remarque: truncate () réinitialise également tout compteur AUTO_INCREMENT (notez également que vous ne pouvez pas tronquer les tables qui ont des contraintes de clé étrangère.)
William Turrell

10
FYI: Turncate ne déclenchera pas d'événements de suppression.
Fusion

1
Si vous voulez vraiment utiliser MyModel::all()->delete(), utilisezforeach (MyModel::all() as $e) { $e->delete() }
Ema4rl

70

Solution Laravel 5.2+ .

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

Saisissez simplement le générateur sous-jacent avec le nom de la table et faites ce que vous voulez. Ça ne pourrait pas être plus ordonné que ça.

Solution Laravel 5.6

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

9
Au cas où quelqu'un d'autre ne comprendrait pas pourquoi cela fonctionne, la classe Model transmet les méthodes au constructeur via la méthode magique __call ici . Étant donné que la classe de modèle elle-même a une méthode de suppression, l'appel de Model :: delete () appelle la méthode Model, lorsque vous voulez vraiment la méthode Builder. Donc, pour obtenir explicitement le générateur, vous pouvez utiliser getQuery ().
kevinAlbs

Cela ne supprime pas non plus les tables liées si vous le souhaitez.
Terje Nesthus

Cela forcera la suppression de tous les enregistrements, que la suppression
réversible soit activée

Model :: whereNotNull ('id') -> delete (); - effectuera une suppression
logicielle

62

Vous pouvez utiliser Model::truncate()si vous désactivez foreign_key_checks(je suppose que vous utilisez MySQL).

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

2
Dans Laravel 4, vous utilisez DB ::
unprepared

vous pouvez également utiliser Schema :: disableForeignKeyConstraints (); & Schema :: enableForeignKeyConstraints ();
Eleazar Resendez

33

J'ai vu les deux méthodes utilisées dans les fichiers de départ.

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

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

//or

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

Même si vous ne pouvez pas utiliser le premier si vous souhaitez définir des clés étrangères .

Impossible de tronquer une table référencée dans une contrainte de clé étrangère

Il peut donc être judicieux d'utiliser le second.


2
deletece n'est évidemment pas la même chose truncate.
Joel Mellon

2
@sudopeople Il serait vraiment utile de faire la différence. Je pourrais également l'ajouter à ma réponse .
giannis christofakis

4
TRUNCATE ne peut pas être utilisé dans une transaction, car il n'est pas affecté par ROLLBACK. Dans ce cas, cela peut être réalisé avec (nouveau MyModel) -> newQuery () -> delete ().
hammurabi

12

Il existe un moyen indirect:

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

Exemple:

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

Informations sur le générateur de requêtes Laravel: https://laravel.com/docs/5.4/queries


1
@aschipfl pas grand chose à expliquer en fait. Le code exécute le SQL DELETE FROM users WHERE id LIKE '%%'qui correspond à toutes les lignes de la table, supprimant ainsi tout.
Hkan

Cela m'a mis sur mon chemin. J'ai fini par faire un pluck () sur un autre modèle pour obtenir un tableau des ID dont j'avais besoin, puis j'ai utilisé ce tableau pour supprimer tous les enregistrements de mon modèle en utilisant la whereInméthode: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC

9

Je voulais ajouter une autre option pour ceux qui accèdent à ce fil via Google. J'avais besoin d'accomplir cela, mais je voulais conserver ma valeur d'incrémentation automatique qui se truncate()réinitialise. Je ne voulais pas non plus utiliser DB::quoi que ce soit parce que je voulais opérer directement à partir de l'objet modèle. Alors, je suis allé avec ceci:

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

Évidemment, la colonne devra réellement exister, mais dans un modèle Eloquent standard, prêt à l'emploi, la idcolonne existe et n'est jamais nulle. Je ne sais pas si c'est le meilleur choix, mais cela fonctionne pour mes besoins.


Model::delete();accomplira la même chose.
Leng du

5
Malheureusement, Model::delete()lance une exception Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically, du moins dans Laravel 5.0.
Dave James Miller

6

Je n'ai pas pu utiliser Model::truncate()car cela ferait une erreur:

SQLSTATE [42000]: Erreur de syntaxe ou violation d'accès: 1701 Impossible de tronquer une table référencée dans une contrainte de clé étrangère

Et malheureusement Model::delete()ne fonctionne pas (du moins dans Laravel 5.0):

La méthode non statique Illuminate \ Database \ Eloquent \ Model :: delete () ne doit pas être appelée statiquement, en supposant $ this à partir d'un contexte incompatible

Mais cela fonctionne:

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

Cela supprimera toutes les lignes, si vous avez configuré la suppression réversible. Pour supprimer complètement toutes les lignes, y compris celles supprimées de manière réversible, vous pouvez changer comme suit:

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

4

La meilleure façon d'accomplir cette opération Laravel 3semble être l'utilisation de l' Fluentinterface pour tronquer le tableau comme indiqué ci-dessous

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

2

Vous pouvez essayer ce one-liner qui préserve également les suppressions douces:

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


0

Dans la même veine que la réponse de Travis vignon, j'avais besoin des données du modèle éloquent, et si les conditions étaient correctes, je devais supprimer ou mettre à jour le modèle. J'ai fini par obtenir le champ minimum et maximum que j'avais renvoyé par ma requête (au cas où un autre champ serait ajouté à la table qui répondrait à mes critères de sélection) ainsi que les critères de sélection d'origine pour mettre à jour les champs via une requête SQL brute (comme par opposition à une requête éloquente par objet de la collection).

Je sais que l'utilisation de SQL brut viole la belle philosophie de code de laravels, mais il serait difficile de gérer des centaines de requêtes à la place d'une seule.


0

Peut faire un boucle aussi ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}

Techniquement oui ... mais IMO cela semble un peu inutile car il existe de meilleures options de requête unique.
Pete

@Pete je sais .. d'autres ont déjà donné leurs réponses ... j'essayais de répondre à l'autre méthode possible à faire ..
Sam Solomon

1
Cela fonctionne en fait pour moi, car je prévois d'archiver les modèles de la collection en fonction de règles spécifiques, mais aussi de les effacer de cette table quotidienne active.
James Perih

-1

Solution qui fonctionne avec Lumen 5.5 avec des contraintes de clés étrangères:

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

}
return response()->json(['error' => false]);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.