Eloquent: Collections
Introducción
Todos los métodos de Eloquent que devuelven más de un resultado de modelo devolverán instancias de la clase Illuminate\Database\Eloquent\Collection
, incluyendo resultados recuperados a través del método get
o accedidos a través de una relación. El objeto de colección Eloquent extiende la colección base de Laravel, por lo que hereda de forma natural docenas de métodos utilizados para trabajar de manera fluida con el array subyacente de modelos Eloquent. Asegúrate de revisar la documentación de colecciones de Laravel para aprender todo sobre estos métodos útiles.
Todas las colecciones también sirven como iteradores, lo que te permite recorrerlas como si fueran arrays PHP simples:
use App\Models\User; $users = User::where('active', 1)->get(); foreach ($users as $user) { echo $user->name;}
Sin embargo, como se mencionó anteriormente, las colecciones son mucho más poderosas que los arrays y exponen una variedad de operaciones de map / reduce que se pueden encadenar utilizando una interfaz intuitiva. Por ejemplo, podemos eliminar todos los modelos inactivos y luego recopilar el primer nombre de cada usuario restante:
$names = User::all()->reject(function (User $user) { return $user->active === false;})->map(function (User $user) { return $user->name;});
Conversión de Colección Eloquent
Mientras que la mayoría de los métodos de colección de Eloquent devuelven una nueva instancia de una colección de Eloquent, los métodos collapse
, flatten
, flip
, keys
, pluck
y zip
devuelven una instancia de una colección base. Del mismo modo, si una operación map
devuelve una colección que no contiene ningún modelo de Eloquent, se convertirá en una instancia de colección base.
Métodos Disponibles
Todas las colecciones Eloquent extienden el objeto de colección base Laravel; por lo tanto, heredan todos los poderosos métodos proporcionados por la clase de colección base.
Además, la clase Illuminate\Database\Eloquent\Collection
ofrece un conjunto ampliado de métodos para ayudar con la gestión de tus colecciones de modelos. La mayoría de los métodos devuelven instancias de Illuminate\Database\Eloquent\Collection
; sin embargo, algunos métodos, como modelKeys
, devuelven una instancia de Illuminate\Support\Collection
.
append contains diff except find fresh intersect load loadMissing modelKeys makeVisible makeHidden only setVisible setHidden toQuery unique
append($attributes)
El método append
se puede utilizar para indicar que un atributo debe ser añadido para cada modelo en la colección. Este método acepta un array de atributos o un solo atributo:
$users->append('team'); $users->append(['team', 'is_admin']);
contains($key, $operator = null, $value = null)
El método contains
se puede utilizar para determinar si una instancia de modelo dada está contenida en la colección. Este método acepta una clave primaria o una instancia de modelo:
$users->contains(1); $users->contains(User::find(1));
diff($items)
El método diff
devuelve todos los modelos que no están presentes en la colección dada:
use App\Models\User; $users = $users->diff(User::whereIn('id', [1, 2, 3])->get());
except($keys)
El método except
devuelve todos los modelos que no tienen las claves primarias dadas:
$users = $users->except([1, 2, 3]);
find($key)
El método find
devuelve el modelo que tiene una clave primaria que coincide con la clave dada. Si $key
es una instancia de modelo, find
intentará devolver un modelo que coincida con la clave primaria. Si $key
es un array de claves, find
devolverá todos los modelos que tienen una clave primaria en el array dado:
$users = User::all(); $user = $users->find(1);
fresh($with = [])
El método fresh
recupera una instancia actualizada de cada modelo en la colección desde la base de datos. Además, se cargarán de forma anticipada las relaciones especificadas:
$users = $users->fresh(); $users = $users->fresh('comments');
intersect($items)
El método intersect
devuelve todos los modelos que también están presentes en la colección dada:
use App\Models\User; $users = $users->intersect(User::whereIn('id', [1, 2, 3])->get());
load($relations)
El método load
carga de manera anticipada las relaciones dadas para todos los modelos en la colección:
$users->load(['comments', 'posts']); $users->load('comments.author'); $users->load(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);
loadMissing($relations)
El método loadMissing
carga de forma anticipada las relaciones dadas para todos los modelos en la colección si las relaciones no están ya cargadas:
$users->loadMissing(['comments', 'posts']); $users->loadMissing('comments.author'); $users->loadMissing(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);
modelKeys()
El método modelKeys
devuelve las claves primarias para todos los modelos en la colección:
$users->modelKeys(); // [1, 2, 3, 4, 5]
makeVisible($attributes)
El método makeVisible
hace que los atributos sean visibles que normalmente están "ocultos" en cada modelo de la colección:
$users = $users->makeVisible(['address', 'phone_number']);
makeHidden($attributes)
El método makeHidden
oculta atributos que son típicamente "visibles" en cada modelo de la colección:
$users = $users->makeHidden(['address', 'phone_number']);
only($keys)
El método only
devuelve todos los modelos que tienen las claves primarias dadas:
$users = $users->only([1, 2, 3]);
setVisible($attributes)
El método setVisible
sobrescribe temporalmente todos los atributos visibles en cada modelo de la colección:
$users = $users->setVisible(['id', 'name']);
setHidden($attributes)
El método setHidden
sobrescribe temporalmente todos los atributos ocultos en cada modelo de la colección:
$users = $users->setHidden(['email', 'password', 'remember_token']);
toQuery()
El método toQuery
devuelve una instancia del constructor de consultas Eloquent que contiene una restricción whereIn
en las claves primarias del modelo de colección:
use App\Models\User; $users = User::where('status', 'VIP')->get(); $users->toQuery()->update([ 'status' => 'Administrator',]);
unique($key = null, $strict = false)
El método unique
devuelve todos los modelos únicos en la colección. Cualquier modelo con la misma clave primaria que otro modelo en la colección es eliminado:
$users = $users->unique();
Colecciones Personalizadas
Si deseas usar un objeto Collection
personalizado al interactuar con un modelo dado, puedes definir un método newCollection
en tu modelo:
<?php namespace App\Models; use App\Support\UserCollection;use Illuminate\Database\Eloquent\Collection;use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * Create a new Eloquent Collection instance. * * @param array<int, \Illuminate\Database\Eloquent\Model> $models * @return \Illuminate\Database\Eloquent\Collection<int, \Illuminate\Database\Eloquent\Model> */ public function newCollection(array $models = []): Collection { return new UserCollection($models); }}
Una vez que hayas definido un método newCollection
, recibirás una instancia de tu colección personalizada cada vez que Eloquent normalmente devolvería una instancia de Illuminate\Database\Eloquent\Collection
. Si te gustaría usar una colección personalizada para cada modelo en tu aplicación, debes definir el método newCollection
en una clase de modelo base que sea extendida por todos los modelos de tu aplicación.