2

関連するカテゴリに応じて、いくつかの車の部品をフィルタリングしようとしています。パーツには多くのカテゴリ (コードではタグと呼ばれます) を含めることができるため、結合テーブルを使用した HABTM リレーションを選択しました。

フィルタリングはこれまでのところ機能しますが、SQL コマンド IN を使用した Cake との 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 関係を実現するための鍵は、選択した猫の数を取得し、グループ パラメータ内のクエリの数と一致させることです。この行はそれをしました:

$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 に答える