Красноречивый пункт о соответствии отношения принадлежит к

Допустим, я уже загрузил отношения и теперь хочу получить модели, которые им соответствуют. Есть ли способ сделать это объективно, а не напрямую использовать идентификаторы?
Вот пример контроллера, описывающий то, чего я хочу достичь:

public function videos(User $user, Category $category)
{
    $videos = Video::where('user', $user)->where('category', $category)->get();
    // ...
}

Я знаю, что могу сделать это так, но я бы хотел пропустить извлечение идентификатора и оставить его, если возможно, фреймворку:

public function videos(User $user, Category $category)
{
    $videos = Video::where('user_id', $user->id)->where('category_id', $category->id)->get();
    // ...
}

Это просто для знаний и более чистого кода?

thisiskelvin 21.09.2018 13:50

В where('table_column', $value) или where(['table_column' => $value]) вы можете увидеть, что ищет Eloquent Builder. Ответственный код: здесь. Хотя я не вижу выгоды в том, что вы хотели бы сделать, вы могли бы написать какую-то оболочку, которая перезаписывает поведение метода where по умолчанию - НЕ рекомендуется вообще, потому что вы можете потерять больше, чем получить.

Tpojka 21.09.2018 14:16

Или еще, вы можете написать собственный метод в модели видео, который возвращает то, что вам нужно: $userVideosOfCategory = Video::userVideoOfCategory(User $user, Category $category); и логику, которую вы создаете в методе пользовательской модели видео. Логика может быть похожа на policy / gate.

Tpojka 21.09.2018 14:22

Это в основном для более чистого кода. И чтобы реализация не просочилась наружу. Чем меньше вещей в общедоступном API, тем больше я могу изменить позже, не рискуя проблемами совместимости. Также, для ясности, мне не нужно придерживаться метода where. Если мне просто нужно указать имя отношения и объект, я буду счастлив, даже если это отдельный метод, например. whereRelated('user', $user)

HubertNNN 21.09.2018 14:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
4
783
2

Ответы 2

Значит, у вас будет видео, которое принадлежит пользователю, верно? Вы могли бы сделать что-то вроде этого:

В вашей модели пользователя:

public function videos()
{
    return $this->hasMany(Video::class);
}

И тогда вы можете назвать эту функцию как

$user->videos();

или

$this->user->videos->toArray();

Если вы начнете создавать подобные отношения в модели, это может значительно упростить получение данных. Возможно, это не полный ответ, но он определенно на правильном пути. Удачи!

Красноречивые отношения: https://laravel.com/docs/5.7/eloquent-relationships

Это работает с одиночными отношениями, и именно так я делал это в течение некоторого времени, но теперь я попал в пример использования, когда мне нужно проверить 2 отношения, и в будущем их может быть больше, поскольку мой класс будет становиться более сложным.

HubertNNN 21.09.2018 14:56

Возможно, вы захотите проверить "имеет много сквозных" - похоже ли это на те отношения, которые вы будете формировать? laravel.com/docs/5.7/eloquent-relationships#has-many-through

party-ring 21.09.2018 15:07

Это не идеально, но я нашел способ легко это сделать с помощью прицелов. Вот мой код:

trait WhereBelongsTo
{
    /**
     * @param \Illuminate\Database\Eloquent\Builder|self $query
     * @return \Illuminate\Database\Eloquent\Builder|self
     */
    public function scopeWhereBelongsTo($query, $relationship, $value)
    {
        /** @var \Illuminate\Database\Eloquent\Relations\BelongsTo $relationship */
        $relationship = call_user_func([$this, $relationship]);

        $foreignKey = $relationship->getForeignKey();
        $ownerKey = $relationship->getOwnerKey();

        if ($value === null) {
            return $query->whereNull($foreignKey);
        } else {
            return $query->where($foreignKey, $value->$ownerKey);
        }
    }
}

После добавления этой черты в Модель я могу использовать ее так:

public function videos(User $user, Category $category)
{
    $videos = Video::whereBelongsTo('user', $user)->whereBelongsTo('category', $category)->get();
    // ...
}

Другие вопросы по теме