我有3个模型(User
,Message
和Tag
),具有以下关系:
User
hasMany Message
Message
belongssto User
Message
HABTM Tag
Tag
HABTM Message
如果用户已登录,他可能希望查看所有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 :(得分: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
答案 1 :(得分: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,消息模型。