@jazzus

Какой запрос выбрать для скопа?

В модели Product нужно получить объект, принадлежащий авторизованному юзеру.

Запрос 1
public function scopeOfUserBySlug($query, $user, $slug)
    {
        return $query->whereUser_id($user->id)->whereSlug($slug);
    }

Вызывается Product:: ofUserBySlug(Auth::user(), $slug)
Запрос 2
public function ofUserBySlug($user, $slug)
    {
        return $user->products->whereSlug($slug);
    }

Вызывается (new Product)->ofUserBySlug(Auth::user(), $slug)

Что выбрать и почему?
Пс
Сейчас во всем приложении $product = $user->product($slug)
Но т.к. допустил уже несколько ошибок (получал не от авторизованного пользователя и это было незаметно) решил вынести данный запрос в модель. Так правильно делать? Или оставить $user->product($slug) везде? Либо $user->product($slug) убрать в трейт и вызывать Product:: ofUserBySlug(Auth::user(), $slug) А трейт подключить к модели. Хочется, чтобы сразу понятно выглядело, что за запрос. Плюс вдруг нужно будет добавить, что-то к этому билдеру, какой нибудь active, true - и тогда нужно будет во всем приложении менять. В общем лучше наверное вынести. Замен будет много (по данному примеру другие объекты). Как бы вы сделали? (product($slug) –это products->whereSlug($slug);)
  • Вопрос задан
  • 312 просмотров
Решения вопроса 1
Alex_Wells
@Alex_Wells
PHP/Kotlin
Второе - не совсем по теме Eloquent'а. Он про магию, и тут скоупы приходятся к месту. А если нужны будут еще условия? Ну, допустим остаите первым вызов этого метода, а если нужны будут еще условия в виде методов? Вот для чего были созданы скоупы, так что первый вариант - однозначно лучше.

Далее: Product:: под капотом как раз и делает (new Product)-> , только кроме этого он может делать и что-то другое, о чем вы не знаете, поэтому я бы использовал Product:: хотя бы ради этого и какой никакой стандартизации.

Далее: почему бы не сделать $user->products()->whereSlug($slug)? Учитывая контекст, смею предположить что именно такой запрос вам нужен не так уж и часто, а значит это - неплохое решение. Нужен будет эктив - ну добавляете скоуп в модель Product и имеете счастье, типа $user->products()->whereSlug($slug)->isActive(). Последние два метода относятся к конечной модели Product, а значит их дублировать не нужно, а вот релейшены в разных моделях (
$user->products(), $page->products(), $something->products()
) - нужно, так что это правильный вариант.

Тем более, Product не должен быть ответственен за методы юзера (как в вашем втором варианте), а если туда напихать еще несколько от разных моделей, со всякими $active = true - получится каша.

TL;DR: Придерживайтесь того, что предлагает Eloquent, и будет вам счастье.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы