Отношения «One of Many»

Laravel 8.42 поддерживает новые Eloquent-отношения «One of Many» (Один из многих) благодаря пул-реквесту Леннарта Карстенс-Беренса.

One of Many Eloquent Relationship Added to Laravel

Отношение Один-из-многих создает связь Один-к-одному из отношений Один-ко-многим. Например, «последний вход в систему», «первый вход», цена на продукт (то есть получить актуальную цену товара).

Реализовано это фильтрацией пересечения отношений заджойненных самих с собой. Проиллюстрируем это примером запроса из пул-реквеста:

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.