CakePHP查找HABTM

CakePHP查找HABTM,cakephp,has-and-belongs-to-many,Cakephp,Has And Belongs To Many,我有3个模型(用户,消息和标签),具有以下关系: 用户有许多消息 消息属于用户 MessageHABTMTag TagHABTMMessage 如果用户登录,他可能希望看到所有带有标记的消息 $messages = $this->Message->find('all', array( 'conditions' => array("Message.user_id" => $this->uid), 'contain' => array(

我有3个模型(
用户
消息
标签
),具有以下关系:

  • 用户
    有许多
    消息
  • 消息
    属于
    用户
  • Message
    HABTM
    Tag
  • Tag
    HABTM
    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']
            )
         )
    ));

但是,此查找将返回该用户的所有消息。(两个模型中都包含可包含的行为)

在模型消息中添加

**
 * @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')));
此外,最好遵循蛋糕命名约定,如果您有标记(复数)、消息标记(第一个单数第二个复数)、消息(复数)表,则必须有标记、消息标记、消息模型。

子级可包含(标记)不会对父级(消息)执行筛选,这就是返回所有消息的原因。标记本身的CONTANDABLE only place条件,在您的情况下,与$activeTag不匹配的消息仍将返回,但附加了空标记数组,而匹配的消息将返回一个仅包含一个标记$activeTag的数组,但将返回所有消息

出于您的目的,CakepHP建议使用join函数对HABTM进行过滤,它会自动为您加入HASON或BELONGS,但当涉及HABTM时,如果需要,您可能需要自己执行join

假设表按常规命名:

$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);
更多信息请点击此处:

您是真的运行了这段代码还是在这里编写的?因为您在运行此代码时一定遇到了语法错误:
array('Tag'=array(…)
我做了一些更改,这就是出现错误的原因--