.
12 декабря 2013

Yii — фильтрация в CGridView

posted in Yii, Программирование |

Итак, после недолгих изучений Yii было принято решение уже что нибудь начать.
А начать я решил с базы квартир для Риэлтеров.
Имхо, если проект довести до ума, сделать удобным в использовании — за применением не заржавеет.
Вообще, какая разница с чем оперировать — основные принципы в работе в разных отраслях одинаковы.

Вот так взять и начать сразу не вышло :) — всё же нужны какие то реальные данные, с ними интереснее.
Соответственно, первое что было сделано — парсер объявлений о аренде квартир с arenda.ngs.ru (можно чтоб присылали готовый файл за деньги — но я жадный).
Парсеры я привык писать на чистом PHP — единственное отличие от ранее написанных парсеров — этот я ваял в PHPStorm (уже начинаю привыкать — довольно удобная штука).

Со структурой БД сильно заморачиваться не стал — одна табличка с объявлениями — и штук 9 справочных, а-ля ID, NAME (город, район, улица, и т.д.)
С КЛАДР-ом тоже заморачиваться не стал, хотя на всякий случай качнул MySQL выгрузку.

Итак — Yii!!!
Качаю фреймворк 1.1.14 (last stable) с оф.сайта.
Ставлю в режиме WebApp — вуаля, уже какой-никакой работающий каркас сразу есть с работающей авторизацией! (и это мне очень понравилось)
Далее, подключаю к фреймворку MySQL и генератор кода gii и создаю модели для всех созданных ранее в PHPMyAdmin табличек, для основной так же делаю в gii CRUD контроллер.

Табличка CGridView в админской части мне так же понравилась, но пока в ней не отображаются реляционные связи — айдишники выводятся в виде цифр.
Далее «вяжем» реляционные связи — в контролер arenda добавляем

'city'=>array(self::BELONGS_TO, 'City', 'id_city') и т.д.

для фотографий другая связь

'fotos'=>array(self::HAS_MANY, 'Fotos', 'id_arenda')

Далее заходим во вьюшку с гридом и добавляем колонку в виде

        array(
            'name' => 'id_city',
            'filter' => CHtml::listData(city::model()->findAll(array('order'=>'name')), 'id', 'name'),
            'value'=>'$data->city->name'
        ),

так и отображение будет правильным и за одно появится фильтр с сортировкой по возрастанию!

С улицами мне такое решение не понравилось т.к. их очень много — решил сделать поиск по вхождению.
Тут мне помог andy_s с форума на оф.сайте — тема.

Инструкция:
1. во вьюшку добавляем колонку с именем search_street и отображаемыми релационными данными:

array(
  'name' => 'search_street',
  'value'=>'$data->street->name'
),

всё ок — поле для фильтрации добавилось, данные выводятся верно, но пока не фильтрует

2. Добавляем поле в модель

class Arenda extends CActiveRecord {
public $search_street;

3. Добавляем в rules () правило с полем search_street в safe для search

array('search_street, id, title, .....', 'safe', 'on'=>'search'),

4. В самом search () добавляем связанную таблицу и связь между search_street и именем

$criteria->with = array('street');
$criteria->compare('street.name',$this->search_street, true);

В итоге получилась довольно симпатичная и функциональная табличка

Яндекс.Метрика