我正在尝试创建一个将在CActiveDataProvider中使用的CDbWriter,我需要查询多对多关系的另一端的值。
我有以下表格:订单、用户订单和用户
关系声明正确,因此我可以访问$order->users[0]并正确查看数据。
我正在尝试建立以下标准:
$criteria=new CDbCriteria;
$criteria->with = array('users');
if (isset($_SESSION['hideCard'])){
$criteria->condition = "fname != 'Card'";
}
return new CActiveDataProvider(get_class($this), array(
'criteria'=>$criteria,
'pagination'=>array('pageSize'=>40)
));
这基本上意味着,如果设置了会话变量,我希望从DataProvider中隐藏所有fname为"Card"的用户。
关于如何在多对多关系中实现这一点,有什么想法吗?
您必须这样修改代码:
$criteria=new CDbCriteria;
$criteria->with = array('users'); // or just string – 'users';
if (isset($_SESSION['hideCard'])){
$criteria->together = true; // critical fix
$criteria->condition = "users.fname != 'Card'"; // table alias must be set to ensure filtering proper column
}
您应该能够使用:
if (isset($_SESSION['hideCard'])){
$criteria->condition = "users.fname != 'Card'";
}
或者,不管users表的别名是什么,我只是从关系名称中假设它的users
。
我对正在运行的查询进行了分析,并开始构建自己的查询。
这是使它工作的代码。。。
public function searchRecent()
{
$criteria=new CDbCriteria;
$criteria->with = array('users');
$criteria->join = 'LEFT JOIN user_order uo ON t.id = uo.order_id LEFT JOIN user u ON u.id = uo.user_id';
$criteria->order = 't.id DESC';
if (isset($_SESSION['hideCard'])){
$criteria->join .= " LEFT JOIN loyalty_members lm ON lm.user_id = u.id";
$criteria->addCondition("magnetic_id IS NULL");
}
if (isset($_SESSION['hidePango'])){
$criteria->addCondition("u.password != 'PANGO'", "AND");
}
$criteria->group = "t.id";
return new CActiveDataProvider(get_class($this), array(
'criteria'=>$criteria,
'pagination'=>array('pageSize'=>40)
));
}
CActiveDataProvider可以采用模型实例,而不仅仅是其类名。这允许您在模型中预设所有标准。然后您可以在模型中使用"命名作用域"。例如
$model = Order::model();
if (isset($_SESSION['someCond'])) {
$model->someNamedScope();
}
if (isset($_SESSION['otherCond'])) {
$model->otherNamedScope();
}
return new CActiveDataProvider($model, ...)