Yii2 - GridView показывает «(не установлено)», если столбец связанной модели находится в списке и фильтруется - PullRequest
0 голосов
/ 27 января 2020

У меня есть две таблицы / модели Компьютер и системная плата

Computer - со следующими столбцами / полями:

  • id
  • имя
  • mainboard_Id
  • serial_number
  • ...

Mainboard - со следующими столбцами / полями:

  • id
  • name
  • type
  • serial_number
  • ...

Эти модели находятся в отношениях один к одному.

В модели Computer у меня есть следующий метод:

    public function getMainboard() {
        return $this->hasOne(Mainboard::className(), ['id' => 'mainboard_id']);
    }

Представление содержит следующий GridView:

    echo GridView::widget([
      'dataProvider' => $dataProvider,
      'filterModel' => null,
      'columns' => [
        'id',
        'name',
        'mainboard.type',
        'serial_number',

      ],
    ]);

Моя SearchModel ComputerSearch выглядит следующим образом:

class ComputerSearch extends Computer {
  public $mainboardType;

  public function rules() {
      return [
        // ...
          [['mainboardType'], 'safe'],
      ];
  }

  public function search($params) {
      $query = Computer::find();
      $query->innerJoinWith('mainboard'); // Join for andFilterWhere();

      $dataProvider = new ActiveDataProvider([
          'query' => $query,
      ]);

      $this->load($params);

      if (!$this->validate()) {
          return $dataProvider;
      }

      $query->andFilterWhere([Mainboard::tableName() . '.type' => $this->mainboardType]);

      return $dataProvider;
  }
}

Моя проблема: этот код показывает «(не установлено)» для mainboard.type, хотя я получаю все данные, когда вставляю построенный запрос в sql и выполняю его вручную. Когда я уберу строку innerJoinWith() в ComputerSearch, фильтр больше не будет работать, потому что он, конечно, не может найти столбец type в dbo.Computer, но тогда GridView завершен, а поле mainboard.type равно отображается правильно.

Кто-нибудь знает, как я могу отфильтровать для dbo.Mainboard.type и отобразить его в виде Computer?

1 Ответ

0 голосов
/ 28 января 2020

Я бы предложил изменить ваше поле GridView 'mainboard.type' на

echo GridView::widget([
  'dataProvider' => $dataProvider,
  'filterModel' => null,
  'columns' => [
    'id',
    'name',
    [
        'attribute' => 'mainboardType',
        'value' => 'mainboard.type',
    ],
    'serial_number',

  ],
]);

Остальная часть вашего кода выглядит нормально. Во-вторых, если ваша база данных чувствительна к регистру, я бы предложил вручную привести поля к тому же регистру, как это

->andFilterWhere(['like', 'LOWER(mainboard.type)', mb_strtolower($this->mainboardType)])

И, наконец, если вышеприведенное не помогает, попробуйте изменить innerJoinWith для тестирования

->joinWith('mainboard')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...