1. Eloquent ORM
  2. Eloquent: Colecciones

Únete a nuestra comunidad de Telegram @webblend!

Aquí encontrarás fragmentos de código de Laravel y consejos útiles sobre desarrollo web.

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, incluidos los resultados recuperados mediante el método get o accedidos mediante una relación. El objeto de colección de Eloquent extiende la colección base de Laravel, por lo que hereda naturalmente docenas de métodos utilizados para trabajar de manera fluida con la matriz subyacente de modelos de Eloquent. ¡Asegúrate de revisar la documentación de la colección de Laravel para conocer todos estos métodos útiles!

Todas las colecciones también sirven como iteradores, lo que te permite recorrerlas como si fueran simples matrices PHP:

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 potentes que las matrices y exponen una variedad de operaciones de mapas / reducciones que se pueden encadenar mediante una interfaz intuitiva. Por ejemplo, podemos eliminar todos los modelos inactivos y luego recopilar el nombre propio 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 Colecciones Eloquent

Si bien 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 colección base. De manera similar, si una operación map devuelve una colección que no contiene modelos de Eloquent, se convertirá en una instancia de colección base.

Métodos Disponibles

Todas las colecciones de Eloquent extienden la colección base de Laravel; por lo tanto, heredan todos los métodos potentes proporcionados por la clase de colección base.

Además, la clase Illuminate\Database\Eloquent\Collection proporciona un conjunto de métodos adicionales para ayudar con la gestión de las colecciones de tus 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 adjunto 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 tengan una clave primaria en el array dado:

$users = User::all();
 
$user = $users->find(1);

fresh($with = [])

El método fresh recupera una instancia fresca de cada modelo en la colección desde la base de datos. Además, se cargarán ansiosamente 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 ansiosamente las relaciones dadas para todos los modelos de 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 ansiosamente las relaciones dadas para todos los modelos de la colección si las relaciones aún no están 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 de todos los modelos de la colección:

$users->modelKeys();
 
// [1, 2, 3, 4, 5]

makeVisible($attributes)

El método makeVisible hace visibles los atributos que suelen estar "ocultos" en cada modelo de la colección:

$users = $users->makeVisible(['address', 'phone_number']);

makeHidden($attributes)

El método makeHidden oculta atributos que suelen estar "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 anula temporalmente todos los atributos visibles en cada modelo de la colección:

$users = $users->setVisible(['id', 'name']);

setHidden($attributes)

El método setHidden anula 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 de generador de consultas Eloquent que contiene una restricción whereIn en las claves primarias del modelo de la 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. Se eliminan cualquier modelo del mismo tipo con la misma clave primaria que otro modelo en la colección:

$users = $users->unique();

Colecciones Personalizadas

Si deseas utilizar 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
{
/**
* Crea una nueva instancia de la colección de Eloquent.
*
* @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 deseas 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.