【问题标题】:Yii CActiveRecord multi level (nested) joinsYii CActiveRecord 多级(嵌套)连接
【发布时间】:2014-03-22 23:41:13
【问题描述】:

我对 Yii 还很陌生,到目前为止,我已经设法靠自己度过难关,但现在我被困住了。

我有一个复杂的关系数据库(在 MySQL 中实现)。我有他们的模型,它工作正常我唯一的问题是我不知道如何用CDbCriteria进行复杂的查询

该应用程序就像一个问题跟踪器,因此用户可以报告一些问题,并且负责该类型问题的人会与他/她联系。

与问题相关的主要表格:

  • 角色(可以为用户分配多个角色,例如角色可以是“会计”或“开发者”)
  • 问题类型(具有角色/例如会计/的用户可以创建具有一组问题类型的新问题/例如“打印机问题”/
  • 问题(每个问题只能有一种问题类型)

开发人员可以创建诸如“需要新的 PHP 版本”之类的问题,但会计师不能这样做,因此我需要在数据库中查询一组角色的所有可用问题类型。 如果用户有多个角色(开发人员、测试人员),那么我需要这些角色可用的问题类型的联合。 到目前为止它正在工作,但是当我需要更进一步并查询使用这些问题类型提交的所有问题时......我被卡住了。

大概我需要得到以下查询:

SELECT DISTINCT i.* FROM `issue` i
    LEFT JOIN issuetype ON issuetype.id=i.issuetype_id
    RIGHT JOIN role_has_issuetype rit ON rit.issuetype_id=issuetype.id
    RIGHT JOIN role ON role.id=rit.role_id
WHERE role.role IN ('developer','tester') AND i.id IS NOT NULL

我知道我可以直接使用 SQL 查询,但 db 后端将在未来发生变化(很可能是 Oracle),所以我想尽可能地保持抽象以避免更改任何硬编码的 SQL 语句并且“独立于后端”。

模型的相关部分:

class Role extends CActiveRecord
{
    public function relations()
    {
        return array(
            'issuetypes' => array(self::MANY_MANY, 'Issuetype', 'role_has_issuetype(role_id, issuetype_id)'),
            'users' => array(self::MANY_MANY, 'User', 'user_has_role(role_id, user_id)'),
        );
    }
}

class Issuetype extends CActiveRecord
{
    public function relations()
    {
        return array(
        ...
        'issues' => array(self::HAS_MANY, 'Issue', 'issuetype_id'),
        'roles' => array(self::MANY_MANY, 'Role', 'role_has_issuetype(issuetype_id, role_id)'),
    );
}

class Issue extends CActiveRecord
{
    public function relations()
    {
        ...
        'issuetype' => array(self::BELONGS_TO, 'Issuetype', 'issuetype_id'),            
    );
    }
}

我尝试过这样的事情:

Issue::model()->with(
array(
    'issuetype'=>array(
     'select'=>false,
     'joinType'=>'INNER JOIN',
     'condition'=>'issuetype.roles IN ("developer","tester")',
)))->findAll();

它不起作用,因为 issuetype 没有列 roles 它只是一个关系。

我尝试分两步完成。首先获取与角色关联的问题类型,然后获取问题。

第一部分正在使用此代码:

$crit = new CDbCriteria();
$crit->addInCondition('roles.role',array('developer','tester'));
$crit->select = array('id');
$res=Issuetype::model()->with('roles')->findAll($crit);

但我不知道如何在另一个条件中使用$res。 (我什至不确定这种方法是否有效,即使它远非最佳)

我已经阅读了大约十几个 SO 答案,并与 Yii 文档一起阅读了 Yii 论坛,但我发现的示例不足以解决这个问题(至少我无法采用这些代码 我的问题)

我很确定我只是忽略了一些明显的东西,但不幸的是我自己无法弄清楚。

谢谢

【问题讨论】:

    标签: php database activerecord yii


    【解决方案1】:

    解决问题有帮助:)

    我意识到我的错误。我应该这样写的:

    return Issue::model()->with(array(
                                'issuetype.roles'=>array(
                                    'select'=>false,
                                    'joinType'=>'INNER JOIN',
                                    'condition'=>"roles.role IN ('developer','tester')",
                                )))->findAll();
    

    我希望这对将来的某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多