2

我正在尝试根据与它们相关的类别过滤一些汽车零件。一个部分可以有很多类别(在代码中它们被称为标签),所以我选择了带有连接表的 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 是这样的数组:array(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 的部分。

预先感谢您的帮助。

4

1 回答 1

0

多亏了这篇博文,我才可以正常工作:

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

过滤带有所有选定标签的条目似乎有点棘手:实现 AND 关系的关键是获取选定猫的数量并将其与 group 参数内的查询匹配。这条线做到了:

$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);
于 2012-10-02T17:02:51.527 回答