2012-10-02 75 views
2

我試圖根據它們相關的類別過濾一些汽車零件。 零件可以有很多類別(在代碼中稱爲標籤),所以我選擇了與連接表的HABTM關係。用AND條件過濾HABTM

過濾工作到目前爲止,但只有與使用SQL命令IN蛋糕的OR條件。 但我試圖過濾只有所有所選類別的部分,所以我需要在類別數組上使用AND條件。

這裏的來自控制器的提取的代碼:

$this->Part->bindModel(array('hasOne' => array('PartsTagsJoin'))); 

$params['conditions'] = array('AND' => array('PartsTagsJoin.tag_id' => $selectedCats)); 
$params['group'] = array('Part.id'); 

$parts = $this->Part->find('all',$params); 
$this->set('parts',$parts); 

$ selectedCats是一個這樣的數組:陣列(1,2,3,4,5);

的SQL輸出爲:

'SELECT `Part`.`id`, `Part`.`name`, `Part`.`image`, `Part`.`image_dir`, `Part`.`time_created`, `Part`.`time_edited`, `Part`.`user_id`, `Part`.`editor_id`, `Part`.`notice`, `User`.`id`, `User`.`username`, `User`.`password`, `User`.`usergroup_id`, `User`.`realname`, `PartsTagsJoin`.`id`, `PartsTagsJoin`.`part_id`, `PartsTagsJoin`.`tag_id` 
FROM `c33rdfloor`.`parts` AS `Part` 
LEFT JOIN `c33rdfloor`.`users` AS `User` ON (`Part`.`user_id` = `User`.`id`) 
LEFT JOIN `c33rdfloor`.`parts_tags_join` AS `PartsTagsJoin` ON (`PartsTagsJoin`.`part_id` = `Part`.`id`) 
WHERE `PartsTagsJoin`.`tag_id` IN (1, 4, 8, 24)' 

我如何篩選有每一個通過$ selectedCats陣列致力於ID部分。

非常感謝您的幫助。

回答

0

我得到它的工作多虧了這篇博客文章:

http://nuts-and-bolts-of-cakephp.com/2008/08/06/habtm-and-join-trickery-with-cakephp/

這似乎是有點棘手與所有選擇標記過濾條目: 實現一個與關係的關鍵是獲取所選貓的數量並將其與組參數內的查詢匹配。 這行做到了:

$params['group'] = array('Part.id','Part.name HAVING COUNT(*) = '.$numCount); 

在代碼看起來像這樣(有興趣的解決方案的人)結束:

// Unbinds the old hasAndBelongsToMany relation and adds a new relation for the output 
$this->Part->unbindModel(array('hasAndBelongsToMany'=>array('PartsTag'))); 
$this->Part->bindModel(array('hasOne'=>array(
     'PartsTagsJoin'=>array(
      'foreignKey'=>false, 
      'type'=>'INNER', 
      'conditions'=>array('PartsTagsJoin.part_id = Part.id') 
     ), 
     'PartsTag'=>array(
       'foreignKey'=>false, 
       'type'=>'INNER', 
       'conditions'=>array(
        'PartsTag.id = PartsTagsJoin.tag_id', 
        'PartsTag.id'=>$selectedCats 
))))); 

$numCount = count($selectedCats); // count of the selected tags 

// groups the entries to the ones that got at least the count of the selected tags -> here the 'AND' magic happens 
$params['group'] = array('Part.id','Part.name HAVING COUNT(*) = '.$numCount); 

$parts = $this->Part->find('all', $params); // sends the query with the params 

$this->set('tagCategories', $categories); 
$this->set('selectedCats', $selectedCats); 
$this->Part->recursive = 4; 
$this->set('parts',$parts);