Skip to content

Связи (includes) ​

includes() перечисляет, что принимает include=:

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]),
    ];
}

Связи ​

Путь связи строкой ('posts.comments') разрешает эту связь; каждый префикс пути тоже разрешён.

Вложенные определения ​

Relationship::to('posts', PostQuery::class) описывает связь её собственным определением: под этим путём разрешены его поля, подгрузки связей и агрегаты.

Определения могут ссылаться друг на друга: UserQuery подгружает posts, а PostQuery — author, описанный UserQuery. Определение, которое повторяется на своём же пути, там становится листом, поэтому include=posts.author разрешён с полями UserQuery, а posts.author.posts — нет.

->withFilters() публикует фильтры вложенного определения на корне (см. Фильтры), а ->withSorts() — его сортировки (см. Сортировки).

Агрегаты ​

Relationship::count('posts'), exists, min, max, sum и avg. Они запрашиваются как postsCount, postsExists, postsMaxViews; суффиксы берутся из конфига query-builder.suffixes, а ->as('name') меняет имя. Каждый принимает необязательное замыкание, которое ограничивает запрос к связанной модели.

Связи с замыканием ​

Relationship::callback('recentPosts', fn ($query) => ..., 'posts') загружает связь с условием под собственным именем.

morphTo ​

Relationship::morphTo('commentable', [Post::class => PostQuery::class, Video::class => VideoQuery::class]) описывает morphTo с определением для каждой связанной модели. fields[posts] сужает посты под commentable, а вложенные подгрузки связей типа загружаются только для моделей этого типа.