Aug 13 2013
Yii: фильтрация в связанных таблицах
При разработке CRUD приложения на yii может возникнуть необходимость фильтрации данных в связанных (объединённых) таблицах. Для формирования табличного представления используется виджет GridView. Столбцы задаются в элементе массива “columns”. Если имя столбика задано с использованием точки (например clientCourse.course_id) фильтрация и сортировка у столбца исчезает. Как её вернуть мы ниже и рассмотрим.
Имеем следующее:
Модели “Client”, “ClientCourse” и “CatalogCourse”.
Файл представления client/index.php, содержащий виджет “TbGridView”.
В файле модели “Client” задаём свойство
public $columnCourse;
В метод rules() вносим изменения в правило валидации, добавляем поле columnCourse:
public function rules() { return array( //... // The following rule is used by search(). // Please remove those attributes that should not be searched. array('columnCourse, family, name, patronimic, forwho', 'safe', 'on'=>'search'), ); }
Таблицы объединены следующим образом:
public function relations() { // NOTE: you may need to adjust the relation name and the related // class name for the relations automatically generated below. return array( 'clientCourse'=>array(self::HAS_MANY, 'ClientCourse', 'client_id'), 'catalogCourses'=>array(self::HAS_MANY, 'CatalogCourse', 'course_id', 'through'=>'clientCourse'), ); }
Вносим изменения в метод search возращающий data provider необходимый для фильтрации в виджете:
public function search() { $criteria=new CDbCriteria; $criteria->with = array('clientCourse'); // ... $criteria->together = true; $criteria->compare('clientCourse.course_id', $this->columnCourse); return new CActiveDataProvider($this, array( 'criteria'=>$criteria, 'pagination'=>array( 'pageSize'=>20, ), )); }
В фрагменте clientCourse – название связи (relations), columnCourse – созданное нами свойство в моделе Client.
Код файла представления приобретает следующий вид:
$this->widget('bootstrap.widgets.TbGridView', array( 'id'=>'client-grid', 'type'=>'striped bordered condensed', 'enableHistory'=>true, 'template'=>"{items}\n{pager}", 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( 'family', 'name', 'patronimic', array( 'type'=>'raw', 'name'=>'columnCourse', 'filter'=>CatalogCourse::getAll(), 'value'=>'CatalogCourse::coursesToStr($data->catalogCourses,$data->clientCourse)', ), array( 'class'=>'bootstrap.widgets.TbButtonColumn', 'htmlOptions'=>array('style'=>'width: 50px'), 'afterDelete'=>'function(link,success,data){ if(success) $("#statusMsg").html(data); }' ), ), ));
Из этого файла нас интересует следующий фрагмент описывающий колонку данных:
array( 'type'=>'raw', 'name'=>'columnCourse', 'filter'=>CatalogCourse::getAll(), 'value'=>'CatalogCourse::coursesToStr($data->catalogCourses,$data->clientCourse)', ),
Имени столбика присваиваем имя свойства, созданного в модели Client. В данном случае качестве фильтра используется выпадающий список, значения для которого возвращаются статическим методом CatalogCourse::getAll().