首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CakePHP模型: Containable中的计数(*)

CakePHP模型: Containable中的计数(*)
EN

Stack Overflow用户
提问于 2010-02-22 08:18:48
回答 2查看 9.7K关注 0票数 12

我有一个CakePHP 1.3应用程序,非常喜欢用来获取数据的Containable behavior

假设我有一个带有评论的一对多关系的帖子。我使用Containable来查询(用于分页)所有帖子和相关评论的列表。但我只对每篇文章有多少评论感兴趣。如果不获取所有行的注释,我没有找到任何方法来使用containable实现这个查询。我试过了:

代码语言:javascript
复制
$this->paginate=array(
            'fields' => 'Post.title, Post.created',
            'contain' => array('Comment'=>'COUNT(*) AS count'),
        );

导致‘模型’注释‘与模型’计数‘不相关联’错误消息。

代码语言:javascript
复制
$this->paginate=array(
            'fields' => array('Post.title, Post.created'),
            'contain' => array('Comment'=>array('fields'=>'COUNT(*) AS count'),
        );

不起作用,结果集为每个帖子包含一个空的注释数组,但最后一个除外,它包含计数字段,但具有所有注释的数量,而不仅仅是所属的注释。

我的另一个猜测是

代码语言:javascript
复制
$this->paginate=array(
            'fields' => 'Post.title, Post.created, COUNT(Comment.id)',
            'contain' => array('Comment'=>array('fields'=>''),
        );

但这会导致错误,因为hasMany关系是独立查询的,因此答案表不在帖子条目的查询中。我如何计算一篇帖子的评论数量?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-02-22 17:54:02

要做到这一点,最好的方法是在posts表中设置一个名为comment_count的字段,并将此键添加到注释模型$belongsTo帖子数组:

'counterCache' => true

每当评论发生任何变化时,相关帖子中的comment_count字段都会更新(实际上,它每次都会重新记录,而不仅仅是添加或删除)。

这样更好,因为当您为用户获取数据时,它的速度更快,甚至不会接触到comments表。既然你使用的是可控制的行为,我想速度和轻量级就是你想要的。

票数 11
EN

Stack Overflow用户

发布于 2011-12-10 03:38:28

我也有同样的问题。PawelMysior给出的答案很好,并导致了解决方案。

我在CakePHP书:3.7.4.1.1 counterCache - Cache your count()中找到了更多细节。这是有帮助的,但仍然有点含糊。为了其他人着想,我想提供一些进一步的细节。

我有两个表: Post和Image。当我将一张图片添加到帖子中时,我希望跟踪每篇帖子有多少张图片在帖子索引列表中显示,而不需要在image表上运行额外的count查询。

代码语言:javascript
复制
CREATE TABLE posts
(
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INTEGER UNSIGNED NOT NULL,
title VARCHAR(255),
body TEXT,
created DATETIME,
modified DATETIME,
image_count INTEGER UNSIGNED,
PRIMARY KEY (id)
) ENGINE=InnoDB;

CREATE TABLE images
(
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
post_id INTEGER UNSIGNED NOT NULL,
filename VARCHAR(255),
created DATETIME,
modified DATETIME,
PRIMARY KEY (id)
) ENGINE=InnoDB;

请注意,该image_count位于posts表中。在images表中不需要任何特殊的东西。

代码语言:javascript
复制
class Post extends AppModel
{
    var $name = 'Memory';
    var $hasMany = array(
        'Image' => array(
            'className' => 'Image',
            'foreignKey' => 'post_id',
            'dependent' => false
        )
    );
}

class Image extends AppModel
{
    var $name = 'Image';
    var $belongsTo = array(
        'Post' => array(
            'className' => 'Post',
            'foreignKey' => 'post_id',
            'counterCache' => true
        )
    );
}

请注意,counterCache已添加到Image模型中。在Post模型中不需要任何特殊的东西。

代码语言:javascript
复制
$this->Post->Behaviors->attach('Containable');
$post = $this->Post->find('all', array(
    'conditions' => array('user_id' => 7),
    'order' => array('Post.created DESC'),
    'contain' => array(
        'Post' => array(
            'User' => array('first_name', 'last_name')
        )
    )
));

现在,当我们执行find时,不需要做任何特殊的事情来查找计数,因为它自动是Post结果中的一个字段。请注意下面的image_count

代码语言:javascript
复制
Array
(
[Post] => Array
        (
            [0] => Array
                (
                    [id] => 14
                    [user_id] => 7
                    [title] => Another great post
                    [body] => Lorem ipsum...
                    [created] => 2011-10-26 11:45:05
                    [modified] => 2011-10-26 11:45:05
                    [image_count] => 21
                    [User] => Array
                    (
                        [first_name] => John
                        [last_name] => Doe
                    )
                )
        )
)

需要注意的一件事是,如果将counterCache添加到现有的数据库结构中,则在添加另一个Image之前,Post中的计数将为零。此时,CakePHP将执行实际计数并将image_count更新为正确的数量。

我希望这些额外的信息对某些人有帮助。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2308087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档