2012-08-27 91 views
1

我正在嘗試使用具有特定標記或標記的帖子使用分頁(例如,如果用戶選擇了兩個標記,則會返回包含任一標記的帖子)。HABTM Find with CakePHP 2.0

我有我的帖子表中定義的關係

public $hasAndBelongsToMany = array('Tags' => array(
      'className'    => 'Tags', 
      'joinTable'    => 'posts_tags', 
      'foreignKey'    => 'post_id', 
      'associationForeignKey' => 'tag_id', 
      'unique'     => 'keepExisting')); 

如何使用搜索來檢索與給定的標籤行(名稱或ID,將被罰款)

嘗試:

// other pagination settings goes here 
$this->paginate['conditions']['Tags.id'] = 13; 

給我一個關係不存在的錯誤。

看着調試信息,看起來表格沒有加入Posts_Tags和Tags表格,但是當我調試數據到視圖時,Posts對象包含標籤數據。

我可以找到的大部分文檔似乎都圍繞着早期版本的CakePHP,希望有任何幫助。

+0

檢查外鍵名到您的相關表中。 –

+0

該表的模式如下: CREATE TABLE'posts_tags'( 'id' int(10)unsigned NOT NULL AUTO_INCREMENT, 'post_id' int(10)unsigned NOT NULL, 'tag_id' int(10)無符號NOT NULL, PRIMARY KEY('id'), KEY'post_tags_post_id_fk'('post_id'), KEY'post_tags_tag_id_fk'('tag_id'), 約束'post_tags_post_id_fk'外鍵('post_id')參考'職位('''')在DELETE CASCADE ON UPDATE CASCADE上執行, CONSTRAINT'post_tags_tag_id_fk' FOREIGN KEY('tag_id')REFERENCES'tags'('id')ON DELETE CASCADE ON UPDATE CASCADE ); – user1627061

回答

1

我認爲最好的解決方案是在連接表模型上應用find函數。我之前嘗試過,它工作正常。

/** 
* @see Model::$actsAs 
*/ 
    public $actsAs = array(
     'Containable', 
    ); 

/** 
* @see Model::$belongsTo 
*/ 
    public $belongsTo = array(
     'Post' => array(
      'className' => 'Post', 
      'foreignKey' => 'post_id', 
     ), 
     'Tags' => array(
      'className' => 'Tag', 
      'foreignKey' => 'tag_id', 
     ), 
    ); 
在你的控制器

在PostTag模型

// $tagsId = tags ids 
    $posts = $this->PostTag->find('all', array('conditions' => array('PostTag.tag_id' => $tagsId),'contain' => array('Post'))); 

也是更好的後續蛋糕命名約定,如果有標籤(複數),post_tags(第1特異第二複數) ,帖子(複數)表,你必須有標籤,郵政標籤,郵政模型。

3

我自己找不到令人滿意的解決方案。 我創建了一個行爲來照顧這個。

創建一個名爲HabtmBehavior.php的文件,並將其放入您的應用/模型/行爲文件夾中。 將代碼塊放在那裏並保存文件。

將行爲添加到您的模型:例如public $ actsAs = array('Habtm');

以下是find的用法示例。

<?php $this->Entry->find('all', array('habtm'=>array('Tag'=>array('Tag.title'=>'value to find'))) ?> 

分頁會是這個樣子:

$this->paginate['Entry']['habtm']['Tag'] = array('Tag.title'=>'value to find'); 

您可以自由,只要你想用的habtm陣列中增加額外的型號名稱添加儘可能多的關係。 (只是要小心不要使它複雜,因爲這可能會開始減慢你的查找結果。)

<?php 
class HabtmBehavior extends ModelBehavior { 

    public function beforeFind(Model $model, $options) { 
    if (!isset($options['joins'])) { 
     $options['joins'] = array(); 
    } 
    if (!isset($options['habtm'])) { 
     return $options; 
    } 
    $habtm = $options['habtm']; 
    unset($options['habtm']); 

    foreach($habtm as $m => $scope){ 
     $assoc = $model->hasAndBelongsToMany[$m]; 
     $bind = "{$assoc['with']}.{$assoc['foreignKey']} = {$model->alias}.{$model->primaryKey}"; 

     $options['joins'][] = array(
      'table' => $assoc['joinTable'], 
      'alias' => $assoc['with'], 
      'type' => 'inner', 
      'foreignKey' => false, 
      'conditions'=> array($bind) 
    ); 

     $bind = $m.'.'.$model->{$m}->primaryKey.' = '; 
     $bind .= "{$assoc['with']}.{$assoc['associationForeignKey']}"; 

     $options['joins'][] = array(
      'table' => $model->{$m}->table, 
      'alias' => $m, 
      'type' => 'inner', 
      'foreignKey' => false, 
      'conditions'=> array($bind) + (array)$scope, 
    ); 
    } 
    return $options; 
    } 

} 

希望這有助於。 快樂烘烤。