2013-02-18 61 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