@ukoHka
Всего понемногу

Как правильно использовать связи в Yii2?

При генерации модели Payments через Gii связанные таблицы отобразились только в rules.
Функцию
public function getStates()
    {
        return $this->hasOne(PaymentStates::className(), ['id' => 'state']);
    }
добавил вручную. На основании этой модели сгенерировал PaymentsSearch, где в функции search дописал
$query->joinWith([
         'states' => function ($q2) {
           $q2->select(['name']);
         }
. Далее в контроллере вызывается search и рендерится
return $this->render('list', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);

В list.php используется GridView, где в columns добавил столбец
[
          'attribute' => 'states.name',
          'format' => 'raw',
          'label' => 'Статус платежа',
          'value' => function (Payments $p) {
            switch ($p->state) {
              case 1 : $class = 'fa fa-question'; break;
              case 2 : $class = 'fa fa-times'; break;
              case 3 : $class = 'fa fa-check'; break;
            }
            return Html::tag('div',Html::tag('span','', ['class'=>$class])
                      . ' ' . $p->states->name);
          }
        ]

И вот здесь в строке $p->states->name генерируется ошибка Trying to get property of non-object. Как правильно прописать код, чтобы $p->states возвращал объект PaymentStates?

Самое странное, что этот код работал, но я что-то изменил (вроде бы только добавил полей в таблицу и заново сгенерировал Payments и PaymentsSearch). И теперь я не могу понять, почему это перестало работать и как вообще использовать связи в Yii2.
Также есть связь с классом User, которая в этом же провайдере выводит нужные данные корректно и код там почти такой же
  • Вопрос задан
  • 305 просмотров
Пригласить эксперта
Ответы на вопрос 2
webinar
@webinar Куратор тега Yii
Учим yii: https://youtu.be/-WRMlGHLgRg
Связь getStates выдает null, связь не означает, что у Вас для каждого Payment есть state. Проверьте этот момент и сделайте проверку, либо в коде:
$state = ($p->states)?$p->states->name:'не определено';
return Html::tag('div',Html::tag('span','', ['class'=>$class]). ' ' . $state);

либо в моделе, например так:
public function getStateName()
    {
        $name = 'хз';
        if($this->states)
            $name = $this->states->name;
        return $name;
    }

ну и естественно юзать $model->stateName вместо $model->states->name
Ответ написан
@ukoHka Автор вопроса
Всего понемногу
Вместо
$query->joinWith([
         'states' => function ($q2) {
           $q2->select(['name']);
         }
использовал
$query->with([
         'states'
       ]);

И все стало отображаться корректно. Не знаю, в чем разница между ними, но раньше определенно работало через joinWith.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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