Model cakephp2.xhabtm通过条件查找具有关系的数据

Model cakephp2.xhabtm通过条件查找具有关系的数据,model,find,relationship,has-and-belongs-to-many,cakephp-2.5,Model,Find,Relationship,Has And Belongs To Many,Cakephp 2.5,我在Models Sdirectory和用户之间有如下HABTM关联: class Sdirectory extends AppModel { public $actsAs = array('Containable'); public $hasAndBelongsToMany = array( 'User' => array( 'className' => 'User',

我在Models Sdirectory和用户之间有如下HABTM关联:

class Sdirectory extends AppModel {
    public $actsAs = array('Containable');
    public $hasAndBelongsToMany = array(
        'User' =>
            array(
                'className' => 'User',
                'joinTable' => 'sdirectories_users',
                'foreignKey' => 'sdirectory_id',
                'associationForeignKey' => 'user_id',
                'unique' => true,
                'with' => 'SdirectoriesUser'
            )
    );
}

只是想看看,任何地方都应该有可控制的

class AppModel extends Model {
    public $recursive = -1;
    public $actsAs = array('Containable');
}
所以我在两者之间有一个关系表,数据库名为sdirectories\u users。我的目标是只获取与用户有关系的Sdirectories。在SQL中,它将是:

SELECT * FROM 
    sdirectories, sdirectories_users, users
WHERE
    sdirectories.id = sdirectories_users.sdirectory_id
  AND
    sdirectories_users.user_id = users.id
当我现在调用$this->Sdirectory->find'all',array'contain'=>array'User'时,我会得到所有Sdirectories-如果两者之间存在关系,我会在Sdirectories旁边得到用户数据

这不是我想要的,但我知道,相关的模型可以相互交流,应该可以工作

现在我尝试在CakePHP find方法中设置条件,如上面的SQL语句:

$this->Sdirectory->find('all'
            , array(
                'contain' => array('User', 'SdirectoriesUser'),
                'conditions' => array(
                    'Sdirectory.id = SdirectoriesUser.sdirectory_id',
                    'SdirectoriesUser.user_id = User.id'
                )
            )
);
因此,我得到以下错误:

Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 
'SdirectoriesUser.sdirectory_id' in 'where clause'

SQL Query: SELECT `Sdirectory`.`id`, `Sdirectory`.`parent_directory_id`, `Sdirectory`.`name`,
`Sdirectory`.`is_root_of_share`, `Sdirectory`.`created`, `Sdirectory`.`modified` FROM
`secufile`.`sdirectories` AS `Sdirectory` WHERE `Sdirectory`.`id` =
`SdirectoriesUser`.`sdirectory_id` AND `SdirectoriesUser`.`user_id` = `User`.`id` 
SQL语句的FROM子句中缺少contain中的两个模型。如上所示,在没有条件的情况下,contain可以正常工作。我还尝试从$this->Sdirectory->User…-但我还有一个问题,我需要连接到与Sdirectory关联的其他模型,我需要从Sdirectory而不是从User获取字段

有人知道我是如何得到与一个或多个用户关联的Sdirectories的吗

编辑/更新: 当我尝试以下方法时:

$allSdirectories = $this->Sdirectory->find('all'
            , array(
                'contain' => array(
                    'User' => array(
                        'conditions' => array('SdirectoriesUser.user_id = User.id')
                    )
                )
            )
        );
作为最后一个查询,我得到以下工作sql语句:

SELECT 
    [selected_fields]
FROM
    `secufile`.`users` AS `User` 
JOIN 
    `secufile`.`sdirectories_users` AS `SdirectoriesUser` 
ON 
    (`SdirectoriesUser`.`sdirectory_id` IN (1, 2, [...], 29, 31)        
        AND 
    `SdirectoriesUser`.`user_id` = `User`.`id`) 
WHERE
    `SdirectoriesUser`.`user_id` = `User`.`id`
都很好。现在我还需要第二个条件:

$allSdirectories = $this->Sdirectory->find('all'
            , array(
                'contain' => array(
                    'User' => array(
                        'conditions' => array('SdirectoriesUser.user_id = User.id')
                    )
                )
                ,'conditions' => array('SdirectoriesUser.user_id = Sdirectory.id')
            )
        );

但是我得到了和上面一样的错误:-有人知道,我必须把第二个条件放在哪里吗?我认为解决办法一定很简单,但我看不出…:-/

如果有人对以下内容感兴趣,这里有一个丑陋的解决方案:

        $userId = $this->Auth->user('id');
        $joins = array(
            array('table'=>'sdirectories_users',
                'alias' => 'SdirectoriesUser',
                'type'=>'inner',
                'conditions'=> array(
                    'Sdirectory.id = SdirectoriesUser.sdirectory_id'
                )),
            array('table'=>'users',
                'alias' => 'User',
                'type'=>'inner',
                'conditions'=> array(
                    'User.id = SdirectoriesUser.user_id',
                    'User.id' => $userId
                ))
        );
        $options = array(
            'joins' => $joins,
            'contain' => array(
                'User' => array('fields' => 'id')
            ),
            'fields' => array('DISTINCT Sdirectory.id', 'Sdirectory.*')
        );
        $allSdirectories = $this->Sdirectory->find('all',
            $options
        );
也许其他人知道一种更好、更性感的方法来创建相同的结果,只使用contain和conditions,而不使用硬编码联接?那就好了-

        $userId = $this->Auth->user('id');
        $joins = array(
            array('table'=>'sdirectories_users',
                'alias' => 'SdirectoriesUser',
                'type'=>'inner',
                'conditions'=> array(
                    'Sdirectory.id = SdirectoriesUser.sdirectory_id'
                )),
            array('table'=>'users',
                'alias' => 'User',
                'type'=>'inner',
                'conditions'=> array(
                    'User.id = SdirectoriesUser.user_id',
                    'User.id' => $userId
                ))
        );
        $options = array(
            'joins' => $joins,
            'contain' => array(
                'User' => array('fields' => 'id')
            ),
            'fields' => array('DISTINCT Sdirectory.id', 'Sdirectory.*')
        );
        $allSdirectories = $this->Sdirectory->find('all',
            $options
        );