Saltar contenido

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($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.