@buildok

Yii2 ActiveQuery::joinWith() не получается выбрать поля из связанной таблицы?

Есть таблица Article(id, id_status, descr, ...) и таблица Status(id, code, descr)
В MySQL делаю:
SELECT article.id, article.id_status, article.descr, status.code, status.descr AS sd
FROM article
LEFT JOIN status ON article.id_status = status.id
WHERE status.code = 4;

Это работает. В ActiveRecord:
// Article.php

public function getArtStatus()
{
     return $this->hasOne(Status::className(), ['id' => 'id_status']) ->inverseOf('articles');
}

// Status.php

public function getArticles()
{
   return $this->hasMany(Article::className(), ['id_status' => 'id']);
}


Далее в ArticleController я возвращаю свой ActiveDataProvider:
...
return new ActiveDataProvider([
 'query' =>   $model->find()
      ->select([
            '{{article}}.name', 
            '{{article}}.descr',
            '{{article}}.id_status',
            '{{article}}.createDt',
            '{{status}}.code',
            '{{status}}.descr AS sd'])
     ->joinWith(['artStatus'])
     ->andWhere('{{status}}.scode = :code', [':code' => $code])
     ->orderBy('{{article}}.createDt'),
 ]);


В итоге приходит JSON, в котором нет полей из Status. Как все таки их вытащить?

И еще, если сделать так:
.....
        '{{article}}.descr AS ad', // или 'ad' =>  '{{article}}.descr'
                                .....
        '{{status}}.code',
        '{{status}}.descr'])

то в ответе появляется status.descr, а article.descr пропадает. Какая-то уличная магия. Другие поля из Status не попадают в ответ вообще никак.
Что неправильно?

В лог MySQL попадает такое:
SELECT COUNT(*) 
FROM `article` 
LEFT JOIN `status` ON `article`.`id_status` =
`status`.`id` 
WHERE `status`.code = 4
SHOW FULL COLUMNS FROM `article`
SELECT
 
SELECT `article`.name, `article`.createDt, `article`.descr, `article`.id_status,
`status`.code, `status`.descr AS `sd` 
FROM `article` 
LEFT JOIN `status` ON `article`.`id_status` = `status`.`id` 
WHERE `status`.code = 4 
ORDER BY `article`.createDt LIMIT 20
SELECT * FROM `status` WHERE `id`=4
SHOW FULL COLUMNS FROM `status`
SELECT
  • Вопрос задан
  • 8453 просмотра
Решения вопроса 1
@buildok Автор вопроса
Через var_dump обнаружил, что поля из связанной таблицы все же возвращаются во вложенном массиве ['artStatus']. По какой-то причине ActiveDataProvider вложенные массивы в JSON не добавляет.
Нашел решение, используя SqlDataProvider:
$count = $model->find()
   ->joinWith('artStatus')
   ->andWhere('{{status}}.code = :code', [':code' => $code])
   ->count();          	

return new SqlDataProvider([
   'totalCount' => $count,
   'params' => [':code' => $code],
   'sql' => '
          SELECT article.*, status.code, status.descr AS sdescr
          FROM article
          LEFT JOIN status ON article.id_status = status.id
          WHERE status.code = :code'
]);


Но этот SQL в контроллере мне совсем не нравится. Поэтому создал представление в MySQL, в котором все нужные поля из связанных таблиц. К этому представлению модель и все, можно обойтись без joinWith и т.п.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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