首先我們有兩個模型它們直接有關聯
class Author extends CActiveRecord
{
...
}
class Post extends CActiveRecord
{
...
function relations()
{
return array(
'author'=>array( self::BELONGS_TO, 'Author', 'id_author' ),
);
}
...
}
當以網格形式顯示所有 Post 時,我們希望顯示作者的名字,並且可以通過作者名字中的關鍵字過濾 Post。提供這些功能的最好解決方式(在我看來)是:
首先需要在 Post 模型中添加一個新的屬性,它用來保存搜索的字符串(即要搜索的作者名).也可以使用外鍵列來實現同樣的效果,但是我不喜歡這麼用,在搜索條件中保存搜索的字符串而不是外鍵 id.你還須在搜索條件中將這個新的屬性的規則設置為 safe。
class Post extends CActiveRecord
{
public $author_search;
...
public function rules()
{
return array(
...
array( 'xxx,yyy,author_search', 'safe', 'on'=>'search' ),
);
}
}
現在就可以在搜索條件(標准情況-每個模型都要一個 search 方法)中使用這個屬性了。同時,我們需要使用條件的 ‘with’ 屬性來指定我們的 Post 是通過哪個關系來獲取作者(這種方式只需一次數據庫查詢而不是延遲加載中的多次查詢
<?php $criteria = new CDbCriteria;$criteria->with = array( 'author' ); ... $criteria->compare( 'author.username', $this->author_search, true ); ... ?>
當我們修改搜索函數時,我們對返回的 CActiveDataProvider 添加一個新的功能
<?php
return new CActiveDataProvider( 'Post',
array(
'criteria'=>$criteria,
'sort'=>array(
'attributes'=>array(
'author_search'=>array(
'asc'=>'author.username',
'desc'=>'author.username DESC',
),
'*',
),
),
);
);
?>
配置中排序部分的 attributes允許我們覆蓋默認值。當我們按 author_search字段排序的時候,它將會按照指定的規則排序,最後的 *表示其他字段按默認排序。通過這種方式我們也可以修改默認屬性的排序(例如:用戶指定按 last_name 列排序時,應該使用last_name和first_name結合排序).
到現在為止我們已經為我們的網格顯示做好了前期准備
<?php
$this->widget('zii.widgets.grid.CGridView',
array(
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'title',
'post_time',
array(
'name'=>'author_search',
'value'=>'$data->author->username'
),
array(
'class'=>'CButtonColumn',
),
),
);
);
?>
這就是所有,我們使用用戶名代替用戶ID外鍵列來排序,並且我們可以使用姓名關鍵字搜索.