首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Yii CActiveRecord多级(嵌套)联接

Yii CActiveRecord多级(嵌套)联接
EN

Stack Overflow用户
提问于 2014-03-22 23:41:13
回答 1查看 673关注 0票数 1

我对Yii很陌生,到目前为止我还能靠自己过日子,但现在我被困住了。

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

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

与这一问题有关的主要表格:

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

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

粗略地说,我需要获得以下查询:

代码语言:javascript
复制
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查询,但是数据库后端将来会改变(很可能是Oracle),所以我想尽量保留抽象,以避免更改任何硬编码的SQL语句,并且“后端无关”。

模型的相关部分:

代码语言:javascript
复制
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'),            
    );
    }
}

我试过这样的方法:

代码语言:javascript
复制
Issue::model()->with(
array(
    'issuetype'=>array(
     'select'=>false,
     'joinType'=>'INNER JOIN',
     'condition'=>'issuetype.roles IN ("developer","tester")',
)))->findAll();

它不能工作,因为问题类型没有列roles,它只是一个关系。

我试着分两步做。首先获取与角色相关的问题类型,然后获取问题。

第一部分使用此代码:

代码语言:javascript
复制
$crit = new CDbCriteria();
$crit->addInCondition('roles.role',array('developer','tester'));
$crit->select = array('id');
$res=Issuetype::model()->with('roles')->findAll($crit);

但我不知道如何在另一个标准中使用$res。(我甚至不确定这种方法会不会奏效,即使它远不是最优的)

我读过十几个这样的答案,并与Yii文档一起阅读了Yii论坛,但是我发现的例子并不足以解决这个问题(至少我不能采用这些代码来解决我的问题)。

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

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-23 13:39:27

)沉睡在这个问题上有帮助:)

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

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22585137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档