Eloquent Collections
Eloquent: Collections
Todos los métodos de Eloquent que devuelven más de un resultado de un modelo, devolverán instancias de la clase Illuminate\Database\Eloquent\Collection, incluidos los resultados recuperados a través del método get o obtenidos a través de una relación. El objeto de colección Eloquent extiende la colección base de Laravel (Illuminate\Support\Collection) , por lo que hereda naturalmente decenas de métodos utilizados para trabajar de manera fluida con el array subyacente de los modelos Eloquent.
Todas las colecciones también sirven como iteradores, permitiéndote 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 y reduce que pueden encadenarse usando una interfaz intuitiva. Por ejemplo, podemos obtener todos los modelos que esten activos y luego recopilar el primer nombre de cada usuario:
$names = User::all()->reject(function (User $user) {
return $user->active === false;
})->map(function (User $user) {
return $user->name;
});
Eloquent Collection Conversion
Mientras que la mayoría de los métodos devuelven una nueva instancia de Illuminate\Database\Eloquent\Collection, los métodos collapse, flatten, flip, keys, pluck y zip devuelven una instancia Illuminate\Support\Collection que es la clase base. De igual manera, si una operación de map devuelve una colección que no contiene modelos Eloquent, esta se convertirá en una instancia de la clase base.
Available Methods
Todas las Eloquent Collections extienden el objeto de colección base de Laravel; por lo tanto, heredan todos los métodos potentes proporcionados por la clase base de Collection.
Además, la clase Illuminate\Database\Eloquent\Collection proporciona 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 a cada modelo en la colección. Este método acepta un array de atributos o un único atributo:
$users->append('team');
$users->append(['team', 'is_admin']);
contains($key, $operator = null, $value = null)
El método contains se puede usar para determinar si una instancia del modelo dado está contenida en la colección. Este método acepta una clave primaria o una instancia del 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:
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 del array:
$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, cualquier relación especificada en el método será cargada de manera anticipada:
$users = $users->fresh();
$users = $users->fresh('comments'); //eager loading relation comments
intersect($items)
El método intersect devuelve todos los modelos que 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 manera anticipada las relaciones dadas para todos los modelos en 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 en la colección:
$users->modelKeys();
// [1, 2, 3, 4, 5]
makeVisible($attributes)
El método makeVisible hace visibles los atributos 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 los atributos que normalmente están “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 temporalmente sobreescribe todos los atributos visibles en cada modelo de la colección.
$users = $users->setVisible(['id', 'name']);
setHidden($attributes)
El método setHidden temporalmente sobreescribe 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 query builder de 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. Cualquier modelo que tenga la misma clave primaria que otro modelo en la colección es eliminado.
$users = $users->unique();
Custom Collections
Si deseas usar un objeto de colección personalizado al interactuar con un modelo específico, 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 el método newCollection, recibirás una instancia de tu colección personalizada cada vez que Eloquent devuelva una instancia de Illuminate\Database\Eloquent\Collection.
Si deseas usar una colección personalizada para todos los modelos en tu aplicación, deberías definir el método newCollection en una clase base que sea extendida por todos los modelos de tu aplicación.