我最近有一个关于Finding records via conditions in habtm的问题。现在,我可以搜索我搜索的类别中的帖子。
现在,我的问题是如何检索每个帖子的类别。有时,帖子在此查询中包含一个或多个类别:
$this->set('posts', $this->Category->find(
'first',
array(
'conditions' => array(
'Category.uri' => $uri
),
'contain' => array('Post')
)
));
我想象这样的事情:
$this->set('posts', $this->Category->find(
'first',
array(
'conditions' => array(
'Category.uri' => $uri
),
'contain' => array('Post' => array(
'contain' => 'Category'
))
)
));
这是我的模型的样子。
// Category Model
class Category extends AppModel {
var $name = 'Category';
var $hasAndBelongsToMany = array(
'Post' => array(
'className' => 'Post'
)
);
var $actsAs = array('Containable');
}
// Post Model
class Post extends AppModel {
var $name = 'Post';
var $hasAndBelongsToMany = array(
'Category' => array(
'className' => 'Category'
)
);
var $actsAs = array('Containable');
var $virtualFields = array(
'date_posted' => 'DATE_SUB(Post.created, INTERVAL 7 DAY)'
);
}
示例数据如下:
categories
id name
1 holidays
2 destinations
posts
id title
1 I am a post
2 I am another post
categories_posts
post_id category_id
1 1
2 2
2 1
我正在从假期中检索帖子。
Array
(
[Category] => Array
(
[id] => 3
[name] => holidays
[uri] => holidays
[created] => 2010-11-25 20:43:03
[modified] => 2010-11-25 20:43:03
)
[Post] => Array
(
[0] => Array
(
[id] => 1
[title] => I am a post
),
[1] => Array
(
[id] => 2
[title] => I am a another post
)
)
)
问题是其中一个帖子分为两类。我想也可以获得这些信息。
答案 0 :(得分:3)
关闭。试试这个:
$this->set('posts', $this->Category->find(
'first',
array(
'conditions' => array(
'Category.uri' => $uri
),
'contain' => array('Post' => array('Category'))
)
));
编写这样的控制器代码存在问题:
您可以通过将查找调用移至模型方法来令人满意地纠正这些问题:
// Categories Controller
$this->set('posts', $this->Category->get_posts_with_cats($uri));
// Category Model
function get_posts_with_cats($uri) {
$this->find('first', array(
'conditions' => array('Category.uri' => $uri),
'contain' => array('Post' => array('Category'))
));
}
这使您的代码更加精彩:
PostsController
中,您可以致电:$this->Post->Category->get_posts_with_cats($uri);
。您的代码现在是DRY。在您学习如何嵌套像我向您展示过的可容纳的模型之后,您可能会在未来尝试做类似的事情:
$this->find('first', array(
'conditions' => array('Category.uri' => $uri),
'contain' => array(
'Post' => array(
'Category' => array(
'Tag' => array('Author')
)
)
)
));
好消息?您将从上述方法中获得所需的模型数据(只要您已定义所有这些关系)。
可怕的消息? CakePHP不知道如何针对这样的深层关联优化查询。因此,随着数据库的增长,您将最终向数据库发送数十个(如果不是数千个)SELECT
个{{1}}个查询,从而有效地使您的应用程序进行爬网(如果不是停止) 。)
设计CakePHP的好人正在为CakePHP 2.0开发更好的可容纳行为,但是你必须等到那时才能获得这种精确度。
答案 1 :(得分:1)
我正在离开我的另一个答案,因为它包含了许多可能偶然发现它的人的好信息。至于更优雅地解决你的问题?您需要翻转它的头部并使用ad-hoc连接从Post模型中搜索,如下所示:
// From the CategoriesController
$this->Category->Post->find('all', array(
'joins' => array(
array(
'table' => 'categories_posts',
'alias' => 'CategoryFilter',
'type' => 'inner',
'conditions' => array(
'CategoryFilter.post_id = Post.id'
)
),
array(
'table' => 'categories',
'alias' => 'CategoryUriFilter',
'type' => 'inner',
'conditions' => array(
'CategoryUriFilter.id = CategoryFilter.category_id'
)
)
),
'conditions' => array(
'CategoryUriFilter.uri' => $uri
),
'contain' => array('Category')
));
返回的数组的格式有点不同,但它应该包含您要查找的所有数据。
答案 2 :(得分:0)
我实际上这样做是为了得到我想要的东西:
function getPostsFromCategory($uri) {
return $this->populatePosts($this->find(
'first',
array(
'conditions' => array(
'Category.uri' => $uri
),
'contain' => array('Post' => array('Category'))
)
));
}
function populatePosts($categoryPosts) {
$posts = $categoryPosts['Post'];
$count = count($categoryPosts['Post']);
for ($i = 0; $i < $count; $i++) {
$categories = $this->Post->find('first', array('conditions' => array('Post.id' => $categoryPosts['Post'][$i]['id']),
'contains' => array('Category')));
// unset($categories['Post']);
foreach ($categories['Category'] as $cat) {
$categoryPosts['Post'][$i]['Categories'][] = $cat;
}
unset($categories);
}
return $categoryPosts;
}
我真的不知道这是否可以通过更多的CakePHP-y方式完成:
我返回的内容如下:
Array
(
[Category] => Array
(
[id] => 3
[name] => festivals
[uri] => festivals
[created] => 2010-11-25 20:43:03
[modified] => 2010-11-25 20:43:03
)
[Post] => Array
(
[0] => Array
(
[id] => 28
[title] => A Post
[Categories] => Array
(
[0] => Array
(
[id] => 3
[name] => festivals
[uri] => festivals
[created] => 2010-11-25 20:43:03
[modified] => 2010-11-25 20:43:03
)
[1] => Array
(
[id] => 4
[name] => destinations
[uri] => destinations
[created] => 2010-11-28 13:04:52
[modified] => 2010-11-28 13:04:52
)
)
)
)