【问题标题】:Yii MANY_TO_MANY and CDbCriteriaYii MANY_TO_MANY 和 CDbCriteria
【发布时间】:2012-09-10 08:11:06
【问题描述】:

我正在尝试创建一个将在 CActiveDataProvider 中使用的 CDbCriteria,我需要在多对多关系的另一侧查询一个值。

我有以下表格: 订单、用户订单和用户

关系已正确声明,因此我可以访问 $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”的所有用户。

关于如何在多对多关系中实现这一点的任何想法?

【问题讨论】:

    标签: php activerecord yii


    【解决方案1】:

    你必须像这样修改你的代码:

    $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
    }
    

    【讨论】:

      【解决方案2】:

      你应该可以使用:

      if (isset($_SESSION['hideCard'])){
          $criteria->condition = "users.fname != 'Card'";
      }
      

      或者无论用户表的别名是什么,我只是从关系名称中假设它的users

      【讨论】:

      • 我试过了,得到了未知的列。我有 3 个表,order、user 和 user_order,关系在 Order 对象中定义为“用户”。
      • 你能看到正在为关系生成的 SQL,它是否包括 users 表,如果是,它叫什么/上面有哪些列。
      • SELECT t.id AS t0_c0, t.business_id AS t0_c1, t.t.service AS t0_c2.t0_c2.@9 987654334 @ AS t0_c3tbalance AS t0_c4topen_time AS t0_c5tstatus AS t0_c6tcall_waiter AS t0_c7, t.decimals AS t0_c8, t.tstamp AS t0_c9, t.station_name AS t0_c10, t0_c10, @987643 987654359@, t.waiter AS t0_c12, t.billnum AS t0_c13 FROM order t WHERE (users.fname != 's panCard') >
      • 你确定这是唯一的 SQL 吗?它可能会被拆分为多个语句,因为这不会在单个查询中降低关系。没有这种情况,一切都按预期工作吗?您还可以澄清一下:您不想要这些用户的任何订单,或者您想要订单,只是不向用户显示?
      【解决方案3】:

      我对正在运行的查询进行了分析,并开始构建自己的查询。

      这是使它工作的代码......

      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)
              ));
          }
      

      【讨论】:

        【解决方案4】:

        CActiveDataProvider 可以采用模型实例,而不仅仅是其类名。这允许您在模型中预设所有标准。然后你可以在你的模型中使用'named scopes'。例如

        $model = Order::model();
        
        if (isset($_SESSION['someCond'])) {
            $model->someNamedScope();
        }
        if (isset($_SESSION['otherCond'])) {
            $model->otherNamedScope();
        }
        
        return new CActiveDataProvider($model, ...)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-04-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多