Php Yii向CGridView中的虚拟属性添加过滤器并使其可排序
我有以下型号:Php Yii向CGridView中的虚拟属性添加过滤器并使其可排序,php,yii,yii-components,Php,Yii,Yii Components,我有以下型号: User列{id、用户名、密码、用户类型} Admin带有列{id、user\u id、full\u name,…等} 编辑器包含列{id、user\u id、full\u name等} 关系是 User:'admin'=>数组(self::HAS_ONE,'admin','User_id'),'editor'=>数组(self::HAS_ONE,'editor','User_id'), Admin:“用户”=>数组(self::属于“用户”、“用户id”), 编辑器:“用户”=
User
列{id、用户名、密码、用户类型}
Admin
带有列{id、user\u id、full\u name,…等}
编辑器
包含列{id、user\u id、full\u name等}
关系是
User
:'admin'=>数组(self::HAS_ONE,'admin','User_id'),'editor'=>数组(self::HAS_ONE,'editor','User_id'),
Admin
:“用户”=>数组(self::属于“用户”、“用户id”),
编辑器
:“用户”=>数组(self::属于“用户”、“用户id”),
现在我在User
模型中设置了一个虚拟属性fullName
,如下所示
public function getFullName()
{
if($this->user_type=='admin')
return $this->admin->full_name;
else if($this->user_type=='editor')
return $this->editor->full_name;
}
我可以在gridview中显示虚拟属性fullName
,但如何向属性添加筛选器并使其在gridview中可排序
UPADTE 1:
我根据@Jon的答案更新了models 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,
));
}
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):
到
顺便说一句,thanx@Jon.这里要做的就是有效地向结果集中添加一个计算列。假设在用于获取结果的SQL查询中,您将加入
Admin
和Editor
表,因此Admin.full\u name
和Editor.full\u name
是计算所需值所涉及的两列
由于至少有一个Admin.full_name
和Editor.full_name
始终为NULL
,因此计算最终值的公式为
public $calculatedName;
现在您已经有了计算公式,需要执行以下步骤:
CDbCriteria
CSort
CActiveDataProvider
CGridView
$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
作为列名
如果我弄错了一些细节,我会道歉,因为我实际上并没有运行这个
更新:如果指定CDbCriteria,Yii不喜欢它。选择作为字符串,该字符串包含任何不用于分隔列的逗号(例如用于分隔合并的参数的逗号)。谢天谢地,CDbCriteria
还允许以数组形式传入列,这就解决了这个问题。我更新了上面的代码以匹配
对于任何好奇的人来说,令人不快的代码是。我不知道我做错了什么,但我一直收到这个错误CDBEException:活动记录“用户”试图选择一个无效的列“合并(管理员全名)”。注意,该列必须存在于表中,或者是一个别名为的表达式。@dInGd0nG:你没有做错什么,我发布的答案正好与Yii的一个小怪癖相冲突。请参阅update.okey。更新工作正常。但我不能使用$criteria->compare('fullName',$this->calculatedName,true)
当我在CGridView过滤器中进行搜索时,出现以下异常情况CDbCommand无法执行SQL语句:SQLSTATE[42S22]:未找到列:1054“where子句”中的未知列“calculatedName”。执行的SQL语句是:SELECT COUNT(DISTINCTt
id
)从(editor
user\u id
=t
t
t
id
id
)上(admin
用户id
用户id
)上的左外连接admin
),其中(计算名称如:ycp0)@dInGd0nG:如果您发布相关代码作为问题的更新,这将非常有用。无论如何,我认为要在列上进行筛选,您需要手动添加它,例如$criteria->condition=“COALESCE(…)LIKE“%$var%””
,用一个适当的带引号的表达式替换$var
。计算列确实很麻烦。
COALESCE(Admin.full_name, Editor.full_name, '')
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,
));