【问题标题】:Sum of a field with hasMany in cakephpcakephp 中带有 hasMany 的字段的总和
【发布时间】:2010-10-22 22:49:37
【问题描述】:

我在 cakephp 中有两个模型,Link 和 Vote。

我想获得我的链接模型中每个链接的投票总和。 这是我的 findAll 函数的打印:

[1] => Array
    (
        [Link] => Array
            (
                [id] => 1
                [url] => http://www.google.com
                [date_added] => 2010-08-19 11:36:56
                [valid] => 1
            )

        [Vote] => Array
            (
                [0] => Array
                    (
                        [link_id] => 1
                        [user_id] => 0
                        [vote] => 3
                    )

                [1] => Array
                    (
                        [link_id] => 1
                        [user_id] => 4
                        [vote] => 4
                    )

            )

    )

我想要的是这个(注意 votes 属性):

[1] => Array
    (
        [Link] => Array
            (
                [id] => 1
                [url] => http://www.google.com
                [date_added] => 2010-08-19 11:36:56
                [valid] => 1
                [votes] => 7
            )

        [Vote] => Array
            (
                [0] => Array
                    (
                        [link_id] => 1
                        [user_id] => 0
                        [vote] => 3
                    )

                [1] => Array
                    (
                        [link_id] => 1
                        [user_id] => 4
                        [vote] => 4
                    )

            )

    )

但我不知道我应该在哪里计算选票的总和。

【问题讨论】:

  • 你尝试了什么?什么没用?我们希望您在提问之前付出一些努力。
  • 嗯,这不是一个很好的评论!

标签: php cakephp cakephp-1.3


【解决方案1】:

您可以在您的链接模型中创建一个虚拟字段“投票”。 http://book.cakephp.org/view/1608/Virtual-fields

var $virtualFields = array(    
    'votes' => 'COUNT ...'
);

【讨论】:

  • 是的,我尝试在我的链接模型中使用虚拟字段,但如果没有完整的 SQL 查询,我无法让它工作。
  • 那有什么问题?
  • 感觉有点“脏”,我希望可以不使用 SQL 对它们求和,我想抽象这个操作,使其不依赖于数据库管理系统。跨度>
  • 编写 SQL 不应仅仅因为您的框架帮助您编写大部分 SQL 代码而感到“肮脏”。现在,您可以实现为您的 has_many 模型添加虚拟字段的行为,并且它创建的 SQL 取决于您在 app/config.php 中选择的数据库引擎。对我来说似乎有点矫枉过正,但你可能需要这样的东西。
【解决方案2】:

尝试使用CakePHP counterCache Sum of a field with hasMany in cakephp

1) 将新字段添加到表 'links' - links.vote_count

2)

<?php class Vote extends AppModel {
       var $belongsTo = array(        
              'Link' => array('counterCache' => true)    
       );} 
?>   

3) 从现在开始,每次添加或删除与 Link 关联的投票时,vote_count 中的数字都会自动调整。

【讨论】:

    【解决方案3】:

    我知道这是 2010 年的一个帖子,但我遇到了很多麻烦,因为它是第一个 Google 结果。

    另一种选择是在父 Link 模型中使用 afterFind,如下所示:

    public function afterFind($results, $primary = false) {
    
        if(($this->findQueryType=='count') || $primary == false) return $results;
    
        foreach ($results as $key => $val) {
            if(isset($val['Vote'])) {
                $votes = Hash::extract($val, 'Vote.{n}.vote');
                $results[$key]['Link']['votes'] = array_sum($votes);
            }
        }
    
        return $results;
    }
    

    现在,每当您在 Link 上执行 find() 并返回 Vote 对象时(例如,当使用 'Contain' 调用 find 时),您的 Link 对象将包含投票总和。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多