Фильтр и поиск в GridView
Фильтр и поиск в GridView
Здравствуйте. Есть колонка в гридвью в которой данные представлены внешним ключем к другой таблице. Проблему вывода данных из этой таблицы, вместо ключа я решил просто:
['attribute' => 'autor', 'value' => function($model){
return $model->user->username;
}],
Теперь данные выводятся не малозначимыми айдишниками, а как положено - имена пользователей, к которым эти айди относятся.
Проблема: как вы наверное уже поняли, поиск все так же осуществляется исключительно по айдишнику из основной таблицы, а по имени пользователя из связанной таблицы поиск невозможен. Как решить эту проблему? Заранее спасибо.
['attribute' => 'autor', 'value' => function($model){
return $model->user->username;
}],
Теперь данные выводятся не малозначимыми айдишниками, а как положено - имена пользователей, к которым эти айди относятся.
Проблема: как вы наверное уже поняли, поиск все так же осуществляется исключительно по айдишнику из основной таблицы, а по имени пользователя из связанной таблицы поиск невозможен. Как решить эту проблему? Заранее спасибо.
Re: Фильтр и поиск в GridView
Все верно, но поиск по связанным таблицам в двух словах не рассказать.
Вам очень сильно поможет google "поиск по связанным данным yii2".
Но еще лучше советую посмотреть: Вебинар от ElisDN (Дмитрий). Там как раз ваша тема рассматривается (Дмитрий всегда очень подробно рассматривает любые вопросы, если покажется удобным - увеличьте скорость просмотра).
Вам очень сильно поможет google "поиск по связанным данным yii2".
Но еще лучше советую посмотреть: Вебинар от ElisDN (Дмитрий). Там как раз ваша тема рассматривается (Дмитрий всегда очень подробно рассматривает любые вопросы, если покажется удобным - увеличьте скорость просмотра).
Осторожно! Вы общаетесь с новичком
Re: Фильтр и поиск в GridView
Все, решил, если кому интересно и может пригодиться, то:
1. Создаем статическую функцию в классе АктивРекорд основной таблицы, которая возвращает все айдишники авторов и подтягивает к ним имена со связанной таблицы соответствующие айдишникам из основной. После формирует массив "id" => "username" и возвращает его. Пример -
public static function getAutorList()
{
$sql = 'SELECT DISTINCT autor, username FROM articles JOIN users ON autor = users.id';
$autors = self::findBySql($sql)->asArray()->all();
$autorList = [];
foreach ($autors as $autor) {
$autorList[$autor['autor']] = $autor['username'];
}
return $autorList;
}
2. Вызывает эту функцию в качестве параметра "filter" нужного столбца в ГридВью. Пример -
['attribute' => 'autor', 'filter' => Articles::getAutorList(), 'value' => function($model){
return $model->user->username;
}],
Все. Теперь не только в столбцах отображаются данные из связанной таблицы, но и в поле поиска в выпадающем списке.
1. Создаем статическую функцию в классе АктивРекорд основной таблицы, которая возвращает все айдишники авторов и подтягивает к ним имена со связанной таблицы соответствующие айдишникам из основной. После формирует массив "id" => "username" и возвращает его. Пример -
public static function getAutorList()
{
$sql = 'SELECT DISTINCT autor, username FROM articles JOIN users ON autor = users.id';
$autors = self::findBySql($sql)->asArray()->all();
$autorList = [];
foreach ($autors as $autor) {
$autorList[$autor['autor']] = $autor['username'];
}
return $autorList;
}
2. Вызывает эту функцию в качестве параметра "filter" нужного столбца в ГридВью. Пример -
['attribute' => 'autor', 'filter' => Articles::getAutorList(), 'value' => function($model){
return $model->user->username;
}],
Все. Теперь не только в столбцах отображаются данные из связанной таблицы, но и в поле поиска в выпадающем списке.
Re: Фильтр и поиск в GridView
И фильтрация работает? А сортировка ? А сколько запросов в БД идет по факту?
Последний раз редактировалось girmate 2018.02.13, 22:10, всего редактировалось 1 раз.
Осторожно! Вы общаетесь с новичком
Re: Фильтр и поиск в GridView
Да я смотрю, но все запомнить не реально, а видео которые он пишет огромны и искать в них что-то - та ещё задачка.girmate писал(а): ↑2018.02.13, 21:55 Все верно, но поиск по связанным таблицам в двух словах не рассказать.
Вам очень сильно поможет google "поиск по связанным данным yii2".
Но еще лучше советую посмотреть: Вебинар от ElisDN (Дмитрий). Там как раз ваша тема рассматривается (Дмитрий всегда очень подробно рассматривает любые вопросы, если покажется удобным - увеличьте скорость просмотра).
Re: Фильтр и поиск в GridView
Некоторые его видео я пересматривал по 6(!) раз. И вы не поверите, поскольку я еще очень начинающий - я всегда находил что-то новое при каждом новом просмотре. Иногда даже полезно спустя полгода просто пересмотреть видео. Я всегда, там где можно смотрю на скорости +20-25%. Просто Дмитрий старается не упустить ничего важного. И трудно найти золотую середину. Одним материал легкий - им только нюансы показать. А другим, наоборот, нужно разжевать.
В свое время прошел его курс по ООП. Он очень сильно мне помог (не реклама). Теперь я может и много где еще буду лапшекодить. Но на некоторые вещи взглянул совершенно по-новому. И если до курса от Дмитрия по ООП я любые рецепты смотрел и радовался, то сейчас есть те видео, которые считаю вредными (например "yii для блондинок" (или как-то так), тот что на youtube). Такие видео сразу закрываю - они вредят (пусть автор курса простит меня). Нужны сервисы, репозитории и прочие полезные фишки, чтобы код был легко читаемым, тестируемым, в перспективе без особых сложностей расширяемым.
Как-то я сделал знакомому интернет-магазин. После того, как прошел курс по ООП стало стыдно за свой магазин. Одновременно получил разочарование - мне оказалось не то чтобы далеко до SamDark, zelenin, ElisDN и многих-многих других товарищей, а мне до них вообще никогда! Не в этой жизни))
Последний раз редактировалось girmate 2018.02.13, 22:25, всего редактировалось 6 раз.
Осторожно! Вы общаетесь с новичком
Re: Фильтр и поиск в GridView
Возможно. Но я помню сортировка не работает по связанным полям. Нужно еще немного колдовать и настраивать. И обратите внимание сколько у вас запросов идет к БД. Если не делаете жадную загрузку - то их будет равно количеству записей на странице в гриде +1 как минимум (не считая других запросов, например схемы). А это очень много.
Осторожно! Вы общаетесь с новичком
Re: Фильтр и поиск в GridView
Сортировка не работает, но она мне и не нужна здесь. Чтобы все извлекалось одним запросом в модели поиска нужно вместо $query = Articles::find() написать $query = Articles::find()->with('user')girmate писал(а): ↑2018.02.13, 22:17Возможно. Но я помню сортировка не работает по связанным полям. Нужно еще немного колдовать и настраивать. И обратите внимание сколько у вас запросов идет к БД. Если не делаете жадную загрузку - то их будет равно количеству записей на странице в гриде +1 как минимум (не считая других запросов, например схемы). А это очень много.
Re: Фильтр и поиск в GridView
Сортировка - пока не нужна). Добейте этот вопрос, рано или поздно пригодится, будете подсматривать.
Осторожно! Вы общаетесь с новичком
Re: Фильтр и поиск в GridView
И если честно, я уже сам забыл, в каких случаях нужен with, а в каких joinwith. Там точно какое-то важное отличие в использовании, но какое хоть убей - не помню.
Осторожно! Вы общаетесь с новичком
Re: Фильтр и поиск в GridView
Разобрался и все сделал как положено, без костылей. Спасибо за наводку!
Re: Фильтр и поиск в GridView
Можно так:['attribute' => 'autor', 'value' => function($model){
return $model->user->username;
}],
Код: Выделить всё
['attribute' => 'autor', 'value' => 'user.username'],
А что конкретно и как вы доделали?
Re: Фильтр и поиск в GridView
Вот здесь https://nix-tips.ru/yii2-sortirovka-i-f ... olyam.html - правильный подход.maleks писал(а): ↑2018.02.14, 08:58Можно так:['attribute' => 'autor', 'value' => function($model){
return $model->user->username;
}],Код: Выделить всё
['attribute' => 'autor', 'value' => 'user.username'],
А что конкретно и как вы доделали?
Re: Фильтр и поиск в GridView
на практике вывела для себя такое правило:
если нужно в условии запроса использовать поля из связанной таблицы, то joinWith
если не нужно, то with
Есть нюансы с количеством записей, но обычно оно не играет особой роли
Re: Фильтр и поиск в GridView
Каноническое решение Вам подсказал ViRuS-X, или с оф.сайта: http://www.yiiframework.com/wiki/621/fi ... w-yii-2-0/.
Но чем больше связанных полей, тем больше запросов вы получите (см.дебаггер). Разумеется в продакшене такие запросы кэшируются, но я решил сделать всё одним запросом, как это обычно делается в классических БД. Может, кому пригодится. На примере таблицы "активных пользователей". Модели, ActiveQuery, Search и View создавались генератором gii.
Есть модель UserActiv. Добавляем в UserActivQuery подключение всех нужных таблиц:
Чтобы в полной мере использовать подключённые столбцы, добавляем переменные в класс (pagename - алиас):
Далее в стандартном сгенерированном UserActivSearch меняем метод search (привожу полностью). Здесь мы переопределяем аттрибуты:
Остальное менять не нужно. В GridView в columns просто добавляете переопределённые:
Пользоваться не обязательно, лично мне такое решение показалось правильным.
Но чем больше связанных полей, тем больше запросов вы получите (см.дебаггер). Разумеется в продакшене такие запросы кэшируются, но я решил сделать всё одним запросом, как это обычно делается в классических БД. Может, кому пригодится. На примере таблицы "активных пользователей". Модели, ActiveQuery, Search и View создавались генератором gii.
Есть модель UserActiv. Добавляем в UserActivQuery подключение всех нужных таблиц:
Код: Выделить всё
public function joinAll()
{
return $this->alias('ua')
->select('ua.*, u.username, pg.objectname pagename')
->innerJoin(User::tableName() . ' u', 'ua.user_id = u.id')
->innerJoin(Page::tableName() . ' pg', 'ua.page_id = pg.id');
}
Код: Выделить всё
class UserActiv extends \yii\db\ActiveRecord
{
public $pagename;
public $username;
...
Далее в стандартном сгенерированном UserActivSearch меняем метод search (привожу полностью). Здесь мы переопределяем аттрибуты:
Код: Выделить всё
public function search($params)
{
$query = UserActiv::find()->joinAll();
$dataProvider = new ActiveDataProvider([ 'query' => $query, ]);
$dataProvider->setSort([
'attributes' => [
'user_agent',
'link',
'ip_address',
'last_action',
'username' => [
'asc' => ['u.username' => SORT_ASC],
'desc' => ['u.username' => SORT_DESC],
'label' => 'Пользователь',
],
'pagename' => [
'asc' => ['pg.objectname' => SORT_ASC],
'desc' => ['pg.objectname' => SORT_DESC],
'label' => 'Ресурс',
],
],
'defaultOrder' => ['last_action' => SORT_DESC],
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
$query->andFilterWhere([
'last_action' => $this->last_action,
]);
// здесь выполняем отбор
$query->andFilterWhere(['like', 'user_agent', $this->user_agent])
// это наши связанные поля
->andFilterWhere(['like', 'pg.objectname', $this->pagename])
->andFilterWhere(['like', 'u.username', $this->username])
->andFilterWhere(['like', 'ip_address', $this->ip_address])
->andFilterWhere(['like', 'link', $this->link]) ;
return $dataProvider;
}
Код: Выделить всё
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[ 'class' => 'yii\grid\SerialColumn'],
'last_action',
// наши связанные поля
'username',
'pagename',
// ..
'ip_address',
'link',
'user_agent',
]
]);
?>
-
- Сообщения: 119
- Зарегистрирован: 2014.06.23, 11:44
- Откуда: Украина
Re: Фильтр и поиск в GridView
Кстати, на вашем плохом "yii для блондинок" в ютубе ваш вопрос, который в начале темы, рассматривался! И там вроде все понятно и не сложно.
Re: Фильтр и поиск в GridView
Топик не мой, поэтому только догадываюсь, что речь идет о либо о сортировке, либо о join. Я уже реализовывал и то и другое, просто кода под рукой не было - и там, в целом, ничего сверхсложного нету. А "видео для блондинок" плохо не потому, что рассказывают про самые основы, а потому что учат говнокодить, формируют узкое мышление, прививая процедурный, а не ООП-шный подход к программированию. И где-то для бложика, ничего плохого в этом нету. Но, как выражался ElisDN - программирование, ничем не отличающееся от обертки mysql - phpmyadmin и толстые контроллеры, неповоротливые модели с божественными методами, делающие все подряд... Вот это я и имел в виду.rosolovsky писал(а): ↑2018.02.15, 00:53 Кстати, на вашем плохом "yii для блондинок" в ютубе ваш вопрос, который в начале темы, рассматривался! И там вроде все понятно и не сложно.
Осторожно! Вы общаетесь с новичком
-
- Сообщения: 119
- Зарегистрирован: 2014.06.23, 11:44
- Откуда: Украина
Re: Фильтр и поиск в GridView
Ну про фильтрацию там рассказано вроде неплохо, как для "блондинок". А так да, ООП подход это не просто так, этим нужно заниматься.