Actualiza Todos los Modelos de una Colección de Laravel

Spread the love

No existe nada mas fácil que actualizar registros usando Eloquent

User::whereIn($ids)->update(['status' => 'inactive']);

Pero el problema se pone interesante cuando necesitamos actualizar modelos que están dentro de una colección después de realizar una consulta.

Y por lo general optamos por la solución mas obvia:

$users = User::get();

foreach ($users as $user) {
    $user->update(['status' => 'inactive']);
}

Esto es perfectamente valido y normal, pero es probable que notes muy rápido que esta solución se vuelve lenta con el tiempo.

Y esto sucede porque en cada vuelta del foreach se requiere ejecutar el comando update en la base de datos y esto no es muy bueno; porque reduce el rendimiento conforme tengas mas modelos en la colección.

Así que la solución mas adecuada seria crear una consulta, sin tener que iterar la colección como lo hicimos al principio.

Y para esto veremos dos opciones que ayudaran con esto.

Actualizar usando modelKeys

$users = User::get();

User::whereIn('id', $users->ModelKeys())->update(['status' => 'inactive']);

En esta solución aprovechas la colección y obtienes todos los Id usando el método modelKeys y y estableces una condición usando whereIn para actualizar solo los modelos de la colección.

Con este cambio ahora solo usaras una sentencia update para actualizar la colección y evitas el problema de tener que iterararla.

update "users" set "status" = ?, "updated_at" = ? where "id" in (?, ?, ?, ?, ?)

Actualizar usando toQuery

Si ya estas usando Laravel 7 o superior, puedes usar el método toQuery para generar el mismo resultado sin tener que recorrer la colección.

La ventaja es que ya no tienes que crear la condición tu mismo y el código queda mucho mas claro.

$users = User::get();

$users->toQuery()->update(['status' => 'inactive']);

Además puedes realizar otras operaciones como por ejemplo borrar todos los modelos de esa colección:

$users->toQuery()->delete();

Si tienes alguna duda deja tu comentario 👍🏼