Models
Eloquent: collections
Every query of models returns an EloquentCollection: a collection with Laravel's collection methods, and a few more
that know about models and their keys.
Introduction#
get(), all(), a has-many relation and an eager load all return an EloquentCollection. It has every method of
Collections, and it is iterable:
const users = await User.whereNotNull('email_verified_at').get()for (const user of users) { console.log(user.name)}Methods that keep the same models, such as filter(), sortBy() and where(), return an EloquentCollection.
Methods that make other values, such as map() and pluck(), return a plain Collection:
const names = (await User.all()).filter((user) => user.email_verified_at !== null).map((user) => user.name)toBase() returns the models in a plain collection.
Available methods#
append(attributes)#
append() adds attributes to every model's toArray() and JSON, as a model's appends does (see
Appending values to JSON).
contains(key)#
contains() tells you whether the collection holds a model, given the model or its key:
const users = await User.all()users.contains(1)users.contains(user)With a key and a value, or a function, it is the collection's contains(). containsStrict() matches a model only by
identity, not by key.
diff(items)#
diff() returns the models whose keys aren't among the models you give:
const users = (await User.all()).diff(await User.whereIn('id', [1, 2, 3]).get())except(...keys)#
except() returns the models without these keys:
const users = (await User.all()).except(1, 2, 3)find(key)#
find() returns the model with that key, or undefined. Given a list of keys, it returns a collection of those
models. findOrFail() throws a ModelNotFoundError instead of returning undefined:
const users = await User.all()const user = users.find(1)const some = users.find([1, 2])fresh(...relations)#
fresh() reads every model again from the database, with the relations you name loaded, in one query:
const users = await User.all()const fresh = await users.fresh('posts')intersect(items)#
intersect() returns the models whose keys are also among the models you give:
const users = (await User.all()).intersect(await User.whereIn('id', [1, 2, 3]).get())load(...relations)#
load() loads relations on every model, one query per relation, and takes the forms with() takes:
const users = await User.all()await users.load('posts', 'roles')await users.load({ posts: (query) => query.where('title', 'like', '%Oriel%') })loadCount() adds the counts, and loadSum(), loadAvg(), loadMin(), loadMax() and loadExists() the other
aggregates, on every model.
loadMissing(...relations)#
loadMissing() loads the relations that aren't loaded yet on each model:
const users = await User.all()await users.loadMissing('posts', 'roles')modelKeys()#
modelKeys() returns the models' primary keys:
const keys = (await User.all()).modelKeys() // [1, 2, 3, 4, 5]makeVisible(attributes) / makeHidden(attributes)#
makeVisible() shows attributes that the model hides in its toArray() and JSON, and makeHidden() hides more, on
every model. setVisible() and setHidden() replace the lists:
const users = (await User.all()).makeVisible(['password', 'remember_token'])const safe = (await User.all()).makeHidden(['email'])only(...keys)#
only() returns the models with these keys:
const users = (await User.all()).only(1, 2, 3)toQuery()#
toQuery() returns a query that matches the collection's models, by their keys, so you can update them all at once:
const users = await User.whereNull('email_verified_at').get()await users.toQuery().update({ email_verified_at: new Date() })The models must all be of one class, and the collection mustn't be empty.
unique(key)#
unique() returns one model per key. Given an attribute or a function, it is the collection's unique():
const users = (await User.all()).unique()merge(items)#
merge() adds the models you give, replacing those with the same key.
Custom collections#
A model returns its collections from newCollection(). Override it to return a subclass of EloquentCollection with
your own methods:
import { EloquentCollection, Model } from '@orieljs/framework'export class TeamCollection<T extends Model> extends EloquentCollection<T> { names(): string[] { return this.map((team) => String(team.getAttribute('name'))).all() }}export class Team extends Model { override newCollection<T extends Model>(this: T, models: T[] = []): TeamCollection<T> { return new TeamCollection(models) }}Every query, relation and eager load of Team then returns a TeamCollection. Their type is still
EloquentCollection, so narrow it to call your methods:
if (teams instanceof TeamCollection) { console.log(teams.names())}