Фильтрация полей gridview для связанных таблиц
Есть GridView в которой надо отобразить данные из связанной модели.
Это можно сделать двумя способами: через объявление публичного виртуального поля в модели и манипулирование наименованиями и значениями этих полей в dataProvider и gridView. Так же есть способ не указывать виртуальное поле, а просто в методе search прописать $query->joinWith с необходимой моделью, а в фильтр добавить условие поиска по id, например:
public function search($params) {
$query = User::find();
$query->joinWith('user');
...
$query->andFilterWhere(['ilike', Settings::tableName() . '.name', $this->settings_id])
...
}
и в гриде можно будет манипулировать через атрибут user.settings_id без проблем.
Первый вариант выглядит очень костыльно (хоть и описан в гайдах фреймворка). А второй вариант не пройдет если будет несколько связанных моделей, например три или четыре
Есть несколько вопросов:
- Нет ли способа, чтобы не писать виртуальное поле, лишь для того, чтобы организовать по нему поиск и чтобы не оперировать чисто идентификатором вида
user_id? Потому что оба способа выглядят просто абсолютными костылями. Зачем нужно было делать возможность обращаться к связанным моделям и полям в gridview, если фильтр пропадает и приходится городить такой странный огород? Как можно сделать поиск и сортировку для связанных полей через одну или даже две, три таблицы не прибегая к виртуальным полям? Например
firm→subdepartment→user→settings→name. Т.е. вgridViewэто будет как:[ 'attribute' => 'Наименование настройки', 'value' => 'subdepartment.user.setttings.name', ]
Ответы (1 шт):
В смысле костыльно?! Создаете SerchModel которая наследуется от класса Modal, добавляете нужные поля для фильтра к примеру $settingName, пишете rulse для данного поля, джойните таблицу. В GridView в элемент ('attribute' => 'settingName') вписываете значения атрибута фильтра, в 'value' как у вас или через 'content' => function ($model) { return $model->user->setttings->name } связи можно оформлять также как и в вывод:
$query = User::find();
$query->joinWith('user.setttings'); // екземпляр User -> Setttings
$query->andFilterWhere(['LIKE', Settings::tableName() . '.name', $this->settingName])
Так работает фильтр в фреймовому, у фреймворка хватает других костелен, так что на такую мелочь как фильтр можно закрыть глаза.