Laravel 8.42 поддерживает новые Eloquent-отношения «One of Many» (Один из многих) благодаря пул-реквесту Леннарта Карстенс-Беренса.
Отношение Один-из-многих создает связь Один-к-одному из отношений Один-ко-многим. Например, «последний вход в систему», «первый вход», цена на продукт (то есть получить актуальную цену товара).
Реализовано это фильтрацией пересечения отношений заджойненных самих с собой. Проиллюстрируем это примером запроса из пул-реквеста:
SELECT * FROM `logins` INNER JOIN ( SELECT MAX(id) AS id FROM logins GROUP BY logins.user_id ) AS latest_login ON latest_login.id = logins.id
В примере модель User
имеет множеством входов в систему. Вот код для задания отношений Один-из-многих:
class User extends Model { public function latest_login() { return $this->hasOne(Login::class)->ofMany(); } }
А вот интерфейс, связанный с ofMany
:
interface SupportsPartialRelations { /** * Отношение является единственным результатом более крупного отношения Один-ко-многим. * * @param string|array|null $column * @param string|Closure|null $aggregate * @param string|null $relation */ public function ofMany($column = 'id', $aggregate = 'MAX', $relation = null); /** * Определяем, это отношение Один-из-многих? * * @return bool */ public function isOneOfMany(); }
Пул-реквест включает в себя два вспомогательных метода, для большей выразительности:
$this->hasOne(Login::class)->latestOfMany(); $this->hasOne(Login::class)->oldestOfMany();
Документация должна появится в ближайшее время, а пока самое удобное место для получения дополнительной информации — это сам пул-реквест #37362. Описание подчеркивает недостатки использования hasOne
для этого типа отношений, чтобы было понятно, когда стоит использовать этот тип отношений.
Автор также предоставил репозиторий с примерами ofMany()
: cbl/laravel-one-of-many. В частности, обратите внимание на модель User
.
Автор: Paul Redmond
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.