[英]How to find models depending on fields in associated models
我正在使用cakephp_2_3_6。 我有三種模型:用戶,組和城市。
組有許多用戶。 城市有很多用戶。 用戶屬於組和城市。
組=>數組(
ID,
組名
)城市=>數組(
ID,
cityName,郵政編碼
)用戶=>數組(
ID,
用戶名,
group_id,
city_id
)
我想向人們提供搜索功能,他們可以根據用戶所在的組的groupName或這些用戶居住的城市名來查找用戶。
public function search(){
$url = $this->params['url'];
$where = $url['where'];
$group = $url['group'];
if(!$where && !$group){
$this->set('foundItems', $this->User->find('all'));
}elseif(!$group && $where){
$this->set('foundItems', $this->User->find('all', array('conditions' => array('User.cityName' => $where))));
}elseif($group && !$where){
$this->set('foundItems', $this->User->find('all', array('conditions' => array('User.groupName' => $group))));
}else{
$this->set('foundItems', $this->User->find('all', array('conditions' => array('User.groupName' => $group), 'conditions' => array('User.cityName' => $where))));
}
如您在上面的代碼中看到的,我使用URL來從表單中傳輸cityName和groupName。 我用此代碼嘗試了其他操作,例如使用city.conditions
代替條件,或使用City.cityName
代替cityName
或User.cityName
。 根據CookBook的JoinTable部分, “ belongsTo”執行自動連接。 因此,我認為它應該以某種方式起作用。
因此,當我嘗試許多不同的方法時,請在本頁和CakePHP CookBook上進行大量閱讀,但沒有找到解決方案,您可以幫助我運行此搜索功能嗎?
這是用戶模型
<?php
class User extends AppModel{
public $useDbConfig = 'sites';
public $belongsTo = array( 'City' => array(
'className' => 'City',
'foreignKey' => 'city_id'),
'Group' => array(
'className' => 'Group',
'foreignKey' => 'group_id')
);
public $validate = array(
'userName' => array(
'rule' => 'notEmpty'
)
);
}
?>
我不明白為什么您在所有三個表中都有groupName。 您確定發布了正確的數據庫結構嗎?
但是也許您正在嘗試做的是:
public function search(){
$url = $this->params['url'];
$where = $url['where'];
$group = $url['group'];
if(!$where && !$group){
$this->set('foundItems', $this->User->find('all'));
}elseif(!$group && $where){
$this->set('foundItems', $this->User->find('all', array('conditions' => array('City.cityName' => $where))));
}elseif($group && !$where){
$this->set('foundItems', $this->User->find('all', array('conditions' => array('Group.groupName' => $group))));
}else{
$this->set('foundItems', $this->User->find('all', array('conditions' => array('Group.groupName' => $group, 'City.cityName' => $where))));
}
(請注意,我只是修改了conditions
選項,如果您的邏輯有效,我並沒有感到沮喪)
我終於弄明白了。
我想做的關鍵是在更深層次的關聯下的ContainableBehavior描述了它是如何完成的。
在我的示例中,我必須像這樣更改find語句:
//attach the behavior on the fly, this has to be done once and only with the main Model
$this->User->Behaviors->load('Containable');
....
$this->User->find('all', array('contain' => array('City' => array('conditions' => array('City.cityName' => $where)), 'Group')));
這樣,我將尋找一個包含City和Group的用戶模型。 現在,我只查找名稱與變量$ where的值匹配的城市中的用戶。
埃迪德
解決方案並不完美,因為這樣,如果將所有用戶分配給與返回該城市的條件相匹配的城市,您將始終獲得所有用戶。 在上面的示例中,所有組也都返回了。
我確切地想要的是:
僅城市中與該用戶的條件和組匹配的用戶。
我如何獲得想要的東西:
然后,我查看並找到了使用連接表的解決方案。 使用內部聯接將僅返回符合條件的城市中的用戶。
如果您只有一個表的條件,則代碼
$this->User->City->recursive = -1;
....
$options['joins'] = array(
array('table' => 'cities',
'alias' => 'City',
'type' => 'inner',
'conditions' => array(
'User.city_id = City.id',
)
)
);
$options['conditions'] = array(
'City.cityName' => $where
);
$result = $this->User->find('all', $options);
如果您有兩個表的條件,則代碼
$this->User->City->recursive = -1;
$this->User->Group->recursive = -1;
....
$options['joins'] = array(
array('table' => 'cities',
'alias' => 'City',
'type' => 'inner',
'conditions' => array(
'User.city_id = City.id',
)
),
array('table' => 'groups',
'alias' => 'Group',
'type' => 'inner',
'conditions' => array(
'User.group_id = group.id',
)
)
);
$options['conditions'] = array(
'City.cityName' => $where,
'Group.groupName' => $group
);
$result = $this->User->find('all', $options);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.