我正在尝试根据与其相关的类别过滤一些汽车零件。 一个部分可以有很多类别(在代码中它们被称为标记),所以我选择了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的部分。
提前感谢您的帮助。
答案 0 :(得分: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);