Если у меня есть 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]);
И поиск работает по мере необходимости! 🙂
Спасибо за помощь!