Yii中添加过滤器,以一个虚拟的属性,CGridView并使其排序(Yii add filter t

2019-06-24 05:25发布

我有以下型号:

User的列{ID,USER_NAME,密码,USER_TYPE}

Admin的列{ID,USER_ID,FULL_NAME,.....等}

Editor与列{ID,USER_ID,FULL_NAME,...等}

和关系是User'admin' => array(self::HAS_ONE, 'Admin', 'user_id'),'editor' => array(self::HAS_ONE, 'Editor', 'user_id'),

Admin'user' => array(self::BELONGS_TO, 'User', 'user_id'),

Editor'user' => array(self::BELONGS_TO, 'User', 'user_id'),

现在,我有设置一个虚拟属性fullNameUser模式,如下

public function getFullName()

{

    if($this->user_type=='admin')

        return $this->admin->full_name;

    else if($this->user_type=='editor')

        return $this->editor->full_name;


}

我可以显示虚拟属性, fullName ,在GridView,但我怎么一个过滤器添加到属性,使其在GridView排序?

UPADTE 1:

我更新了模型搜索()函数按照由@乔恩的答案如下图所示

    public function search()
        {


            $criteria=new CDbCriteria;
            $criteria->select=array('*','COALESCE( editor.full_name,admin.first_name, \'\') AS calculatedName');
            $criteria->with=array('editor','admin');
            $criteria->compare('calculatedName',$this->calculatedName,true);
            $criteria->compare('email',$this->email,true);
            $criteria->compare('user_type',$this->user_type);

            return new CActiveDataProvider($this, array(
                'criteria'=>$criteria,


));
    }

这两个管理员和编辑的名称在GridView正确显示。 但是,当我通过以下发生异常过滤器进行搜索,

CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'calculatedName' in 'where clause'. The SQL statement executed was: SELECT COUNT(DISTINCT `t`.`id`) FROM `user` `t`  LEFT OUTER JOIN `editor` `editor` ON (`editor`.`user_id`=`t`.`id`)  LEFT OUTER JOIN `admin` `admin` ON (`admin`.`user_id`=`t`.`id`)  WHERE (calculatedName LIKE :ycp0) (C:\xampplite\htdocs\yii\framework\db\CDbCommand.php:528)</p><pre>#0 C:\xampplite\htdocs\yii\framework\db\CDbCommand.php(425):

我怎样才能摆脱呢?

更新2:我的错误。 它工作正常,当我改了行

$criteria->compare('calculatedName',$this->calculatedName,true);

$criteria->compare('COALESCE( editor.full_name,admin.first_name, \'\')',$this->calculatedName,true);

和BTW感谢名单@乔恩。

Answer 1:

什么你想在这里做实际上是一个计算列添加到结果集。 试想一下,在用于获取你将加入这两个结果的SQL查询AdminEditor表,因此Admin.full_nameEditor.full_name是将参与计算所需的值两列。

由于至少一个Admin.full_nameEditor.full_name总是将是NULL ,该公式计算出的最终值是

COALESCE(Admin.full_name, Editor.full_name, '')

现在,你有计算的公式,你需要采取下列步骤操作:

  1. 一个读写列添加到您的模型获得的计算列
  2. 创建CDbCriteria连接两个表,包括计算列
  3. 创建CSort描述计算列应该如何影响记录顺序
  4. 创建CActiveDataProvider使用这些标准和排序选项
  5. 订阅数据提供给您的CGridView

因此,首先一个公共属性添加到模型:

public $calculatedName;

然后:

$criteria = new CDbCriteria(array(
    'select' => array(
        '*',
        'COALESCE(Admin.full_name, Editor.full_name, \'\') AS calculatedName',
    ),
    'with'   => array('Admin', 'Editor'),
    // other options here
));

$sort = new CSort;
$sort->attributes = array(
    'calculatedName' => array(
        'asc'  => 'COALESCE(Admin.full_name, Editor.full_name, \'\')',
        'desc' => 'COALESCE(Admin.full_name, Editor.full_name, \'\') DESC',
    ),
    // other sort order definitions here
);

$dataProvider = new CActiveDataProvider('User', array(
    'criteria' => $criteria,
    'sort'     => $sort,
));

最后,使用$dataProvider来填充你的网格; 使用calculatedName作为列名。

道歉,如果我得到了一些细节错了,因为我并没有真正运行这个。

更新:事实证明,如果你指定的Yii不喜欢CDbCriteria.select作为一个字符串和字符串中包含不使用单独的列(如用来分隔参数的逗号任何逗号COALESCE )。 值得庆幸的是CDbCriteria还允许在列传递作为数组,其获取解决此问题。 我更新了上面的代码相匹配。

对于任何人谁是好奇的,有问题的代码是这样 。



文章来源: Yii add filter to a virtual attribute in CGridView and make it sortable