Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Доброго времени суток!
1...
2 ->with(['score' => function ($query) use ($competitor) {
3 $query->whereIn('competitor_id', [$competitor->id]);
4 }])
5 ->with(['score as score_actual' => function ($query) use ($competitor) {
6 $query->whereIn('competitor_id', [$competitor->id])->whereIn('is_actual', [1]);
7 }])
8...
В пятой строчке тупо, на "а вдруг?!", указан алиас для динамического атрибута 'score as score_actual', и это не работает:
Call to undefined relationship [score as score_actual] on model [App\Referee]
Возможно ли какое-то корректное решение, на уровне контроллера, в этой ситуации?
С уважением.
Не в сети
очевидно – добавить на модель App\Referee связь score_actual, с where
Не в сети
Ну, это да. А на уровне контроллера никак? :-(
Считайте, ради интереса уже.
Не в сети
во-первых
Ну, это да. А на уровне контроллера никак?
с помощью ->with() – нет, with грузит конкретные связи и кладёт их в конкретные атрибуты модели. естественно что несмотря на то что score и score_actual связывают referee с одной и той же моделью, у них разная логика и разный смысл, поэтому это разные связи.
если взять абстрактный пример: модель Post и у неё есть поля written_by (belongsTo), approved_by (belongsTo) и связь commented_by (hasMany) – все три связи идут на модель User, но их семантика различается и нет смысла пытаться их объединить как-то в одну, это просто разные связи
я понимаю что ты смотришь на это с точки зрения построения sql-запроса, его таблиц и полей, а не с точки зрения ORM, поэтому у тебя возникает этот вопрос. если смотреть со стороны объектов и их связей, то надо спросить себя – логически связь score_actual – это то же самое что score или нет?
во-вторых
Считайте, ради интереса уже.
я думаю что ты это делаешь не ради интереса а ради оптимизации. и тут тебе такой вопрос – а нужно ли выбирать данные (score_actual) которые у тебя уже есть? ведь в score эти actual уже есть, а поскольку $referee->score это коллекция с полем actual на моделях, тебе вообще ничего не стоит получить эти score_actual из этой коллекции уже в момент когда они нужны!
мой вариант – добавить на App\Referee метод
public function getScoreActualAttribute() {
return $this->score->whereIn('is_actual', [1]);
}
теперь если ты загрузил связь score с нужными тебе условиями, то в $referee->score_actual ты получишь те же данные но с фильтром по actual – на один запрос в базу меньше, данные те же. бери и выводи в шаблоне или обрабатывай в коде как тебе нужно
Не в сети
Да, спасибо, решение очевидно и ответ принят, я так и поступлю.
Каюсь, я действительно не задумывался особо, что из себя представляет, на самом деле, динамический атрибут - поля из JOUN или вложенный SELECT..? Работает, и ладно. Пока не столкнулся с вышеописанной ситуацией.
Конечно же, данные в наборе есть и вот это (css-стили убрал) - работает:
@foreach($referee->score as $score)
@if($score->is_actual == 0)
<small>{{$score->score}}</small>
<small>{{ date('d.m.Y', strtotime($score->created_at)) }}</small>
@else
<small>{{$score->score}}</small>
<small>{{ date('d.m.Y', strtotime($score->created_at)) }}</small>
<br>
@endif
@endforeach
Это, как ты наверняка догадался, отображается история баллов, и, в зависимости от значения поля is_actual применяется тот или иной стиль.
А если, где-то в другом месте, нужно отобразить только актуальный балл?
А может, есть способ в представлении как-то вытащить актуальный балл из этого,
->with(['score' => function ($query) use ($competitor) {$query->whereIn('competitor_id', [$competitor->id]);
При условии, что актуальный всегда существует, если какие-то баллы вообще имеются. Ну, и если это поэлегантнее, чем в цикле перебрать :-)
Ну, а ежели это никак, воспользуюсь "модельным" решением.
Не в сети
во-первых, использование и <br> для позиционирования элементов? я очень надеюсь что это черновая вёрстка и никогда не пойдёт в продакшен
во-вторых, а актуальный балл – он в единственном числе существует или в нескольких? я не понял самой структуры – referree назначают баллы, а потом из них вычисляется какой-то один актуальный и он сохраняется в ту же таблицу вместе со всеми остальными баллами что ли?
Не в сети
Эх... Ладненько, в принципе, ответ на вопрос я получил, за что "весьма Вами благодарен" :-)
Не в сети
Страницы 1