¿Cómo eliminar todas las filas de una tabla usando Eloquent?

135

Mi conjetura era usar la siguiente sintaxis:

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

Pero eso no funcionó. Estoy seguro de que es súper simple, ¡pero he buscado documentación sobre el tema y no puedo encontrarla!

Pete
fuente

Respuestas:

279

La razón MyModel::all()->delete()no funciona porque en all()realidad dispara la consulta y devuelve una colección de objetos Eloquent.

Puede utilizar el método truncado, esto funciona para Laravel 4 y 5:

MyModel::truncate();

Eso elimina todas las filas de la tabla sin registrar eliminaciones de filas individuales.

bilalq
fuente
1
He agregado una solución Laravel 3 a mi pregunta, para futuros lectores.
Pete
39
Agradable. Esto también funciona en Laravel 5 si alguien más
busca
14
Nota: truncate () también restablece cualquier contador AUTO_INCREMENT (también tenga en cuenta que no puede truncar las tablas que tienen restricciones de clave externa).
William Turrell
10
FYI: Turncate no activará eventos de eliminación.
Fusion
1
Si realmente quieres usar MyModel::all()->delete(), usaforeach (MyModel::all() as $e) { $e->delete() }
Ema4rl
70

Laravel 5.2+ solución.

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

Simplemente tome el constructor subyacente con el nombre de la tabla y haga lo que sea. No podría ser más ordenado que eso.

Solución Laravel 5.6

\App\Model::query()->delete();
Yauheni Prakopchyk
fuente
9
En caso de que alguien más estuviera confundido acerca de por qué esto funciona, la clase Modelo reenvía métodos al Constructor a través del método mágico __call aquí . Debido a que la clase de modelo en sí tiene un método de eliminación, llamar a Model :: delete () llama al método de Modelo, cuando realmente desea el método Builder. Entonces, para obtener el constructor explícitamente, puede usar getQuery ().
kevinAlbs
Esto tampoco elimina las tablas relacionadas si lo desea.
Terje Nesthus
Que obligará a eliminar todos los registros, independientemente de si suave Eliminar está encendido o apagado
shalini
Modelo :: whereNotNull ('id') -> delete (); - hará una eliminación suave cuando la eliminación suave esté activada
shalini
61

Puede usarlo Model::truncate()si lo deshabilita foreign_key_checks(supongo que usa MySQL).

DB::statement("SET foreign_key_checks=0");
Model::truncate();
DB::statement("SET foreign_key_checks=1");
Fortex
fuente
2
En Laravel 4, usa DB ::
unprepared
también puede usar Schema :: disableForeignKeyConstraints (); & Schema :: enableForeignKeyConstraints ();
Eleazar Resendez
33

He visto que ambos métodos se han usado en archivos semilla.

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

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

//or

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

Aunque no puede usar el primero si desea establecer claves foráneas .

No se puede truncar una tabla a la que se hace referencia en una restricción de clave externa

Por lo tanto, podría ser una buena idea usar la segunda.

giannis christofakis
fuente
2
deleteobviamente no es lo mismo que truncatesi.
Joel Mellon
2
@sudopeople Sería realmente útil señalar la diferencia. También podría agregarlo a mi respuesta .
giannis christofakis
44
TRUNCATE no se puede usar en una transacción, ya que no se ve afectado por ROLLBACK. En ese caso, esto se puede lograr con (new MyModel) -> newQuery () -> delete ().
hammurabi
12

Hay una forma indirecta:

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

Ejemplo:

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

Información del generador de consultas Laravel: https://laravel.com/docs/5.4/queries

Rejaul
fuente
1
@aschipfl no tiene mucho que explicar en realidad. El código ejecuta el SQL DELETE FROM users WHERE id LIKE '%%'que coincide con todas las filas de la tabla, eliminando así todo.
Hkan
Esto me puso en camino. Terminé haciendo un pluck () en otro modelo para obtener una matriz de las ID que necesitaba, luego usé esa matriz para eliminar todos los registros de mi modelo usando el whereInmétodo: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC
9

Quería agregar otra opción para aquellos que llegan a este hilo a través de Google. Necesitaba lograr esto, pero quería conservar mi valor de incremento automático que se truncate()restablece. Tampoco quería usar DB::nada porque quería operar directamente fuera del objeto modelo. Entonces, fui con esto:

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

Obviamente, la columna tendrá que existir realmente, pero en un modelo Eloquent estándar y listo para usar, la idcolumna existe y nunca es nula. No sé si esta es la mejor opción, pero funciona para mis propósitos.

lookitsatravis
fuente
Model::delete();logrará lo mismo.
Leng
55
Lamentablemente Model::delete()arroja una excepción Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically, al menos en Laravel 5.0.
Dave James Miller
6

No pude usar, Model::truncate()ya que sería un error:

SQLSTATE [42000]: Error de sintaxis o infracción de acceso: 1701 No se puede truncar una tabla a la que se hace referencia en una restricción de clave externa

Y desafortunadamente Model::delete() no funciona (al menos en Laravel 5.0):

El método no estático Illuminate \ Database \ Eloquent \ Model :: delete () no debe llamarse estáticamente, suponiendo $ this desde un contexto incompatible

Pero esto funciona:

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

Eso eliminará suavemente todas las filas, si tiene configurada la eliminación suave. Para eliminar completamente todas las filas, incluidas las eliminadas temporalmente, puede cambiar esto:

(new Model)->newQueryWithoutScopes()->forceDelete()
Dave James Miller
fuente
4

La mejor manera de lograr esta operación Laravel 3parece ser el uso de la Fluentinterfaz para truncar la tabla como se muestra a continuación

DB::query("TRUNCATE TABLE mytable");
Pete
fuente
2

Puede probar este one-liner que conserva las eliminaciones suaves también:

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

Solución simple:

 Mymodel::query()->delete();
Ali Filali
fuente
0

En una línea similar a la respuesta de Travis vignon, requería datos del modelo elocuente, y si las condiciones eran correctas, necesitaba eliminar o actualizar el modelo. Terminé obteniendo el campo mínimo y máximo que había devuelto por mi consulta (en caso de que se agregara otro campo a la tabla que cumpliera con mis criterios de selección) junto con los criterios de selección originales para actualizar los campos a través de una consulta SQL sin procesar (como opuesto a una consulta elocuente por objeto en la colección).

Sé que el uso de SQL sin procesar viola la hermosa filosofía de código de Laravels, pero sería difícil soportar cientos de consultas en lugar de una.

Sidney
fuente
0

Puede hacer un bucle también ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}
Sam Solomon
fuente
Técnicamente sí ... pero IMO parece un poco innecesario ya que hay mejores opciones de consulta única.
Pete
@Pete lo sé ... otros ya dieron sus respuestas ... Estaba tratando de responder el otro método posible para hacer ...
Sam Solomon
1
Esto realmente funciona para mí, ya que planeo archivar los Modelos en la colección en función de reglas específicas, pero también eliminarlos de esa tabla activa diaria.
James Perih
-1

Solución que trabaja con Lumen 5.5 con restricciones de claves foráneas:

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

}
return response()->json(['error' => false]);
Alain Berrier
fuente