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!

Pete
la source

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.

bilalq
la source
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();
Yauheni Prakopchyk
la source
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");
Fortex
la source
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.

giannis christofakis
la source
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

Rejaul
la source
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.

lookitsatravis
la source
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()
Dave James Miller
la source
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");
Pete
la source
2

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

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

solution simple:

 Mymodel::query()->delete();
ali filali
la source
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.

Sidney
la source
0

Peut faire un boucle aussi ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}
Sam Solomon
la source
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]);
Alain Berrier
la source