Skip to content

Includes ​

includes() lists what include= accepts:

php
public function includes(): array
{
    return [
        'profile',
        'posts.comments',
        Relationship::to('author', UserQuery::class),
        Relationship::count('posts'),
        Relationship::max('posts', 'views'),
        Relationship::callback('recentPosts', fn ($query) => $query->where('created_at', '>', now()->subWeek()), 'posts'),
        Relationship::morphTo('commentable', [Post::class => PostQuery::class, Video::class => VideoQuery::class]),
    ];
}

Relations ​

A relation path as a string ('posts.comments') allows the relation; every prefix of the path is allowed as well.

Nested definitions ​

Relationship::to('posts', PostQuery::class) describes the relation by its own definition: its fields, includes and aggregates are allowed under the path.

Definitions may refer to each other: UserQuery includes posts, and PostQuery includes author, described by UserQuery. A definition that repeats on its own path is a leaf there, so include=posts.author is allowed with the fields of UserQuery, while posts.author.posts is not.

->withFilters() publishes the filters of the nested definition on the root (see Filters), and ->withSorts() its sorts (see Sorts).

Aggregates ​

Relationship::count('posts'), exists, min, max, sum and avg. They are requested as postsCount, postsExists, postsMaxViews; the suffixes come from the query-builder.suffixes config, and ->as('name') changes the name. Each takes an optional closure that constrains the related query.

Callback relations ​

Relationship::callback('recentPosts', fn ($query) => ..., 'posts') loads a relation with a constraint, under its own name.

morphTo ​

Relationship::morphTo('commentable', [Post::class => PostQuery::class, Video::class => VideoQuery::class]) describes a morphTo with a definition per related model. fields[posts] narrows the posts under commentable, and the nested includes of a type are loaded only for the models of that type.