Сортировка и фильтрация данных в GridView Yii2, где столбец отсутствует в базе данных

Если у меня есть 2 поля в db – вероятность и влияние, и мне нужен столбец в GridView, где эти два поля умножаются. Мне удалось добавить его туда, как:

[ 'attribute' => 'priority', 'format' => 'raw', 'value' => function ($model) { return $model->influence * $model->probability; }, ], 

Но не может обрабатывать сортировку, потому что этот столбец не находится в db, а добавление фильтров к $ query вызывает только ошибки.

  $query = Risks::find(); $query->select(`probability*influence AS priority`); $dataProvider = new ActiveDataProvider([ 'query' => $query, ]); 

Обновлено (работает Asc и Desc, но не с фильтрами)

 public function search($params) { $query = Risks::find(); $query->joinWith(['author', 'proj']); $query->select('*, (probability * influence) as priority'); $dataProvider = new ActiveDataProvider([ 'query' => $query, ]); $dataProvider->setSort([ 'attributes' => [ // 'id', 'probability', 'risks', 'influence', 'del' => [ 'asc' => ['risks.del' => SORT_ASC], 'desc' => ['risks.del' => SORT_DESC], ], 'priority' => [ 'asc' => ['priority' => SORT_ASC], 'desc' => ['priority' => SORT_DESC], 'label' => 'Priority', ], 'proj' => [ 'asc' => ['projects.name' => SORT_ASC], 'desc' => ['projects.name' => SORT_DESC], ], 'author' => [ 'asc' => ['users.name' => SORT_ASC], 'desc' => ['users.name' => SORT_DESC], ] ] ]); $this->load($params); if (!$this->validate()) { // uncomment the following line if you do not want to any records when validation fails // $query->where('0=1'); return $dataProvider; } $query->andFilterWhere([ 'id' => $this->id, 'proj_id' => $this->proj_id, 'author_id' => $this->author_id, 'influence' => $this->influence, 'probability' => $this->probability, //'del' => $this->del, ]) ->andFilterWhere(['like', 'projects.name', $this->proj]) ->andFilterWhere(['like', 'users.name', $this->author]); $query->andFilterWhere(['like', 'risks', $this->risks]); $query->having('priority = '. $this->priority); //$query->having(['priority' => $this->priority]); return $dataProvider; } 

ШАГ 1: добавьте функцию геттера на вашу базовую модель Risks :

 public function getPriority() { return ($this->probability * $this->influence); } 

ШАГ 2: добавьте priority атрибута к вашей модели RisksSearch и настройте свои правила.

 /* your calculated attribute */ public $priority; /* setup rules */ public function rules() { return [ /* your other rules */ [['priority'], 'safe'] ]; } 

ШАГ 3: отредактируйте метод search (), чтобы включить вычисленный priority поля

 public function search($params) { $query = Person::find(); $query->select('*, (probability * influence) as priority'); $dataProvider = new ActiveDataProvider([ 'query' => $query, ]); /** * Setup your sorting attributes * Note: This is setup before $this->load($params) */ $dataProvider->setSort([ 'attributes' => [ 'id', 'priority' => [ 'asc' => ['priority' => SORT_ASC], 'desc' => ['priority' => SORT_DESC], 'label' => 'Priority', 'default' => SORT_ASC ], ] ]); ... 

ШАГ 4: добавьте $query->andFilterWhere() после $this->load($params) чтобы иметь возможность фильтровать вычисленное поле

 // use the operator you wish, ie '=', '>', '<' etc $query->andFilterWhere(['=', '(probability * influence)', $this->priority]); 

Удалены

  $query->select('*, (probability * influence) as priority'); 

изменено

  'priority' => [ 'asc' => ['(probability * influence)' => SORT_ASC], 'desc' => ['(probability * influence)' => SORT_DESC], 'label' => 'Priority', ], 

и после $ this-> load ($ params);

  $query->andFilterWhere(['=', '(probability * influence)', $this->priority]); 

И поиск работает по мере необходимости! 🙂

Спасибо за помощь!