我有一个存储帖子和主题的应用程序,并使用Topic_Posts表连接它们。
申请的关联如下:
Post.php
class Post extends AppModel
{
public $name = 'Post';
public $belongsTo = 'User';
public $hasMany = array('Answer');
// Has many topics that belong to topic post join table... jazz
public $hasAndBelongsToMany = array(
'Topic' => array('with' => 'TopicPost')
);
}
Topic.php
class Topic extends AppModel
{
public $hasMany = array(
'TopicPost'
);
}
TopicPost.php
class TopicPost extends AppModel {
public $belongsTo = array(
'Topic', 'Post'
);
}
当用户查看主题时,例如/topics/view/topicname
我想显示包含该主题的所有帖子。
到目前为止,我在我的TopicsController中为视图提供了以下方法:
public function view ( $slug )
{
$topic = $this->Topic->find('first', array('conditions'=>array('Topic.slug'=>$slug)));
$this->set('topic', $topic);
$this->set('title_for_layout', $topic['Topic']['title'] . ' – Topics');
$this->paginate = array
(
'Post' => array
(
'limit'=>15,
'conditions'=>array
(
'Post.status'=>array(1,2),
'TopicPost.topic_id' => $topic['Topic']['id'],
),
'order'=>array('Post.datetime'=>'desc'),
'contain'=>array('User'=>'Profile', 'TopicPost')
)
);
$posts = $this->paginate('Post'); // this one
$this->set('posts', $posts);
}
因此我可以使用Posts和TopicPosts,我已将public $uses = array('Topic','TopicPost','Post');
添加到控制器的顶部,并使所有模型都可以包含。
所以基本上我需要找到在数据库模型TopicPosts中匹配的帖子,用于我正在查看的主题的id。
答案 0 :(得分:2)
我无法让它以“正确”的方式工作。我不确定这是不是蛋糕或其他东西的错误,但分页功能只是拒绝让步..正确的方法可能是在你的Post模型中编写自己的paginate函数,有一些信息如何在食谱中做到这一点。
与此同时,我为您提供以下解决方法。它不是最优的(至少不是没有缓存)但它有效。如果遇到性能问题,你可以以正确的方式执行此操作,但在此之前,下面的代码应该这样做。
public function view ( $slug )
{
$topic = $this->Topic->find('first', array('conditions'=>array('Topic.slug'=>$slug)));
$this->set('topic', $topic);
$this->set('title_for_layout', $topic['Topic']['title'] . ' – Topics');
// step 1: get post IDs related to your topic
$postIDs = $this->Topic->TopicPost->find
(
'list',
array
(
'fields' => array('TopicPost.post_id'),
'conditions' => array('TopicPost.topic_id' => $topic['Topic']['id'])
)
);
$this->paginate = array
(
'Post' => array
(
'limit'=>15,
'conditions'=>array
(
'Post.status' => array(1,2),
// step 2: include them in your paginate conditions
'Post.id' => $postIDs,
),
'order' => array('Post.datetime'=>'desc'),
)
);
$posts = $this->paginate('Post');
$this->set('posts', $posts);
}
(请注意我在我的测试中删除了一些内容,因为我的应用中没有一些东西,所以不要忘记把它放回去)
答案 1 :(得分:1)
我认为您的模型关系存在问题,我不明白为什么您在帖子模型上有HABTM关系,当您在TopicPost
上实际模仿它(using the Has-many-through method)时模特本身。如果你不想使用内置于蛋糕中的HABTM行为(我不怪你),你应该设置这样的关系:
class PostTopic extends AppModel { // note PostTopic, name should be alphabetical
public $belongsTo = array('Post', 'Topic');
}
class Post extends AppModel {
public $hasMany = array('PostTopic');
}
class Topic extends AppModel {
public $hasMany = array('PostTopic');
}
然后,要获取相关帖子或主题的ID,您只需加载PostTopic
课程并进行搜索:
// ie in Post Controller
$this->paginate($this->Post->PostTopic, array('PostTopic.topic_id' => $post['PostTopic']['topic_id']));
我的网站上有类似的设置,用户可以将产品添加到他们的库存中,这是一种HABTM关系,但附加了更多数据。请参阅此处的产品,广告资源和用户模型,了解更复杂的example。
答案 2 :(得分:0)
来自问题评论:
还要注意数据库结构和关系可以正常工作 可以使用TopicPost提取帖子的主题,所以我知道 工作,它只是获得一个似乎没有的主题的帖子 工作...
是的,因为您为Post->主题设置了HABTM,但没有为Topic-> Post设置。{ 2.0书定义了一个与你的一样的例子(但使用食谱和成分)来描述用例。
hasMany和HABTM之间的主要区别在于它之间的链接 HABTM中的模型并不是唯一的。例如,我们即将加入 我们的食谱模型使用HABTM的成分模型。用西红柿 作为我奶奶的意大利面配方的成分不会“用完” 成分。我也可以用它做沙拉食谱。
使用Post
(您的标签/类别的名称)Topic
也可以这样说。就像他们的例子一样:
请记住在Ingredient模型中定义HABTM关联if 您在使用Ingredient模型时想要获取配方数据。
或者,在您的情况下,主题模型。
所以这是你应该使用的模型:
class Post extends AppModel
{
public $name = 'Post';
public $belongsTo = 'User';
public $hasMany = array('Answer');
// Has many topics that belong to topic post join table... jazz
public $hasAndBelongsToMany = array(
'Topic' => array('with' => 'TopicPost')
);
}
class Topic extends AppModel
{
// Has many posts that belong to topic post join table... jazz
public $hasAndBelongsToMany = array(
'Post' => array('with' => 'TopicPost')
);
}
现在,除非你正在做一些特别的事情,否则你真的不需要TopicPost
,但事实并非如此。而且,虽然您可以使用该模型将Topic
添加到帖子中(反之亦然),但我建议您使用build in方法处理HABTM保存。有关保存HABTM的详细信息,请查看this page。
如果您决定将其删除,请确保为每个模型中的HABTM选项定义连接表和条件per the docs