dIn*_*0nG 9 php yii yii-components
我有以下型号:
User 列{id,user_name,password,user_type}
Admin 列{id,user_id,full_name,..... etc}
Editor 列{id,user_id,full_name,... etc}
关系是
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'),
现在我fullName在UserModel中设置了一个虚拟属性,如下所示
public function getFullName()
{
if($this->user_type=='admin')
return $this->admin->full_name;
else if($this->user_type=='editor')
return $this->editor->full_name;
}
Run Code Online (Sandbox Code Playgroud)
我可以fullName在gridview中显示虚拟属性,但是如何在属性中添加过滤器并使其在gridview中可排序?
UPADTE 1:
我根据@Jon的答案更新了模型search()函数,如下所示
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,
));
}
Run Code Online (Sandbox Code Playgroud)
网格视图中正确显示了管理员和编辑者的名称.但是当我通过过滤器进行搜索时,会发生以下异常,
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):
Run Code Online (Sandbox Code Playgroud)
我怎么能摆脱这个?
更新2:我的错误.当我改变线路时它工作正常
$criteria->compare('calculatedName',$this->calculatedName,true);
Run Code Online (Sandbox Code Playgroud)
至
$criteria->compare('COALESCE( editor.full_name,admin.first_name, \'\')',$this->calculatedName,true);
Run Code Online (Sandbox Code Playgroud)
和btw thanx @Jon.
您在此处尝试执行的操作是将计算列添加到结果集中.想象一下,在用于获取结果的SQL查询中,您将同时连接Admin和Editor表,因此Admin.full_name,Editor.full_name这两个列将参与计算所需的值.
由于至少有一个Admin.full_name并且Editor.full_name总是如此NULL,计算最终值的公式将是
COALESCE(Admin.full_name, Editor.full_name, '')
Run Code Online (Sandbox Code Playgroud)
现在您已经计算了公式,您需要采取以下步骤:
CDbCriteria连接两个表并包含计算列的CSort描述计算列应如何影响记录顺序的方法CActiveDataProvider使用这些条件和排序选项CGridView因此,首先将一个公共属性添加到模型中:
public $calculatedName;
Run Code Online (Sandbox Code Playgroud)
然后:
$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,
));
Run Code Online (Sandbox Code Playgroud)
最后,$dataProvider用来填充你的网格; 使用calculatedName作为列名.
如果我得到一些细节错误,请道歉,因为我实际上并没有这样做.
更新:事实证明,如果您指定CDbCriteria.select为字符串并且该字符串包含任何未用于分隔列的逗号(例如用于将参数分隔的逗号),则Yii不喜欢它COALESCE.值得庆幸的是,CDbCriteria还允许将列作为数组传递,从而解决了这个问题.我更新了上面的代码以匹配.
对于任何好奇的人来说,有问题的代码就是这个.