在CakePHP中计算新的平均值afterSave(或更好的东西?)

时间:2011-07-24 19:10:38

标签: mysql cakephp cakephp-1.3 rating-system

我正在建立一个评级系统,用户可以对1-5星级的评分进行评分。

我想知道是否有办法在afterSave或类似的东西上自动计算特定项目的所有评级(来自于='x'和foreign_key ='y'的评级表)。

我可以在ratings_controller中做到这一点......只是认为在模型中自动完成可能更理想。有人能指出我正确的方向吗?

我很乐意听到CakePHP中存在某种关联设置,允许它为您执行此操作 - 例如:

//Rating model
var $belongsTo = array(
    'Restaurant' => array(
        'averageValue' => 'rating
    )
);

但是 - 我确信这要求很多:)

2 个答案:

答案 0 :(得分:2)

如果你想将平均值保存到items表中的一个字段中,那么afterSave可能就是现在最好的解决方案。

蛋糕可以自动为你做的唯一事情是跟踪一个项目有多少评级(counterCache),而不是其他聚合函数。

virtualField可能不错,但我从来没有将它用于聚合函数,所以我不确定。此外,如果您的评级不经常更改,则会对系统进行不必要的工作。

评级模型:

function afterSave($created){
   $avgValue = $this->Query('SELECT AVG(rating) as rating FROM ratings WHERE ratings.restaurant_id = '.$this->restaurant_id);
   $this->Restaurant->updateRatingAverage($this->restaurant_id,$avgValue[0][0]['rating']);
}

在餐厅模特

function updateRatingAverage($id,$avg){  
   $this->id = $id;
   $this->field('your_average_field_here',$avg);
}

你可能想记录$ avgValue以了解它是如何构建的,但我认为我做对了。

答案 1 :(得分:1)

我需要发帖回答,因为我还不能发表评论。

那么,您(例如)的餐馆有多少评级?在餐馆模型中尝试virtualField,您可以在每次从数据库中获取餐馆时计算评级。如果需要使用AVG(),可能需要像提到的ypercube一样使用GROUP BY。