Model cakephp2.xhabtm通过条件查找具有关系的数据
我在Models Sdirectory和用户之间有如下HABTM关联: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',
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
);