开发者

Sum of a field with hasMany in cakephp

I have two models in cakephp, Link and Vote.

I want to have the sum of the votes for every link in my Link model. Here is a print of my findAll function :

[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
                    )

            )

    )

What I would like to have is this (note the votes attribute) :

[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
                    )

            )

    )

But I have no idea where I'm supposed to do the SUM of the votes.


You can create a virtual field "votes" in your Link model. http://book.cakephp.org/view/1608/Virtual-fields

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


Try to use CakePHP counterCache Sum of a field with hasMany in cakephp

1) Add new field to table 'links' - links.vote_count

2)

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

3) From now on, every time you add or remove a Vote associated to Link, the number within vote_count is adjusted automatically.


I know this is a thread from 2010, but I was having lots of trouble with this and its the first Google result.

Another option is to use afterFind in the parent Link model, like this:

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;
}

Now any time you do a find() on Link that is also returning the Vote object (e.g. when calling find using 'Contain'), your Link object will contain the sum of votes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜