2013-02-18 86 views
2

我有3種型號(UserMessageTag)具有以下關係:CakePHP的發現HABTM

  • User的hasManyMessage
  • Message屬於關聯User
  • MessageHABTMTag
  • TagHABTMMessage

如果用戶已經登錄,他可能希望看到所有Message標記的東西。

$messages = $this->Message->find('all', array(
    'conditions' => array("Message.user_id" => $this->uid), 
    'contain' => array(
     'Tag' => array(
      'conditions' => array(
       'Tag.id' => $activetag['Tag']['id'] 
      ) 
     ) 
    )); 

但是,此查找將返回該用戶的所有消息。 (中可容納的行爲均包含在模型)

+0

你實際運行這段代碼,還是你寫的嗎?因爲你在運行這段代碼時一定得到了一個語法錯誤:'array('Tag'= array(...))' – Jelmer 2013-02-18 23:11:43

+0

我做了一些改變,那就是爲什麼有這個錯誤-.- – 2013-02-18 23:31:10

回答

0

模型中的信息在你的控制器中添加

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

/** 
* @see Model::$belongsTo 
*/ 
    public $belongsTo = array(
     'Message' => array(
      'className' => 'Message', 
      'foreignKey' => 'message_id', 
     ), 
     'Tags' => array(
      'className' => 'Tag', 
      'foreignKey' => 'tag_id', 
     ), 
    ); 

// $tagsId = tags ids 
    $message = $this->MessageTag->find('all', array('conditions' => array('MessageTag.tag_id' => $tagsId),'contain' => array('Message'))); 

也是更好的後續蛋糕命名約定,如果有標籤(複數),message_tags(第一個單數第二個複數),消息(複數)表,你必須有Tag,MessageTag,Message Models。

1

包含在子(標籤)不會對父(消息)執行過濾器,這就是所有消息都返回的原因。只有標籤本身的可容納條件,在你的情況下,不匹配$ activeTag的消息仍然會返回,但附加了空的標籤數組,而匹配的消息將返回一個只包含一個標籤的數組,即$ activeTag,但所有消息會得到回報。

爲了您的目的,CakepHP建議使用連接函數進行HABTM過濾,它會自動爲您連接hasOne或belongsTo,但當涉及到HABTM時,您可能需要自己執行連接(如果需要)。

假設表命名常規:

$this->Message->recursive = -1; 

$options['joins'] = array(
    array('table' => 'messages_tags', 
     'alias' => 'MessageTag', 
     'type' => 'INNER', 
     'conditions' => array(
      'Message.id = MessageTag.message_id', 
     ) 
    )); 

$options['conditions'] = array(
    'MessageTag.tag_id' => $activetag['Tag']['id'], 
    'Message.user_id' => $this->uid); 

$message = $this->Message->find('all', $options); 

更多的信息在這裏: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#joining-tables