Yii框架:通过外键显示关联的表项并搜索它

时间:2013-10-15 13:55:46

标签: php yii

您好我是Yii Framework的新手,我正在关注 Larry Ullman的教程系列。 我有员工模型和部门模型。 部门模型员工模型的关系 has_many departmentId 是员工模型中的外键。

admin 视图中,我有一个搜索栏,后面跟着一个Employee列表,我想显示Department的名称而不是departmentId,还要搜索部门名称。 试一试,我编写了以下代码,其中包含一个与departmentId字段对应的数组。 这个适用于查看操作,但不适用于管理操作

请帮助。

<?php 
echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>
<div class="search-form" style="display:none">
<?php $this->renderPartial('_search',array(
'model'=>$model,
)); 
?>
</div><!-- search-form -->

<?php 
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'employee-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
    'id',
    array(
    'name'=>'departmentId',
    'value'=>$model->department->name,
    ),
    //'departmentId',
    'firstName',
    'lastName',
    'email',
    'ext',
    /*
    'hireDate',
    'leaveDate',
    */
    array(
        'class'=>'CButtonColumn',
    ),
),
)); ?>

2 个答案:

答案 0 :(得分:3)

您的视图操作只是从单个模型生成的列表视图,我假设。此代码在这种情况下不起作用,因为CGridView使用$model->search()指定的CActiveDataProvider返回的数据生成每一行。因此,在这种情况下,$model仅是当前模型,不包含查询生成的数据。

为了实现这一点,value应该是CGridView可以作为PHP代码评估的字符串。所以看起来应该是'value'=>'$data->department->name;',$data是Yii用来向CDataColumn提供当前行的变量。)

答案 1 :(得分:1)

我在gridview中创建额外的可搜索关系列的最佳方法是使用以下模式:

// the model class
class Product extends CActiveRecord {
    // create a custom field in your model class to hold your search data
    public $searchSupplierName;

    // [...]

    // make sure the custom field is safe to set in your rules
    public function rules() {
        return array(
            // [...]

            // add your custom field name to this rule
            array('id, searchSupplierName', 'safe', 'on'=>'search'), 
        );
    }

    // edit your search function 
    public function search() {
        // [...]

        // use the value of the custom attribute as a condition in your search
        $criteria->compare('supplier.name', $this->searchSupplierName,true);

        // you could use something like the following 
        // to make sure you don't fire a lazy loading query 
        // for every result that is shown on the gridview.
        if($this->searchSupplierName)
            $criteria->with = array( 'supplier' );

        // then do something like this if you want to be able to sort on the field
        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
            'sort'=>array(
                'attributes'=>array(
                    'searchSupplierName'=>array(
                        'asc'=>'supplier.name',
                        'desc'=>'supplier.name DESC',
                    ),
                    '*', // this makes sure the rest of the field sorts keep working
                ),
            ),
        ));
    }
}
// in the template
<?php 
$this->widget('zii.widgets.grid.CGridView', array(
    // set the dataprovider to the changed search function output
    'dataProvider' => $model->search(),
    'filter' => $model, // model is an instance of Product in this case (obviously ;)

    // [...]

    'columns' => array(
        // [...]

        // this is the column we care (extra) about
        // notice I still use a custom value here (as @ethan describes in his answer)
        array(
            'name' => 'searchSupplierName',
            'value' => '$data->supplier->name',
        ),
    ),
)); 
?>  

此解决方案适用于(几乎)您想要的任何情况。如果您想在列上进行基于文本的过滤,这是我能想到的最佳解决方案。

但也有other options。例如,如果您只想使用组合框搜索relation_id以找到正确的值,则会less complicated solutions