Рассчитать новое среднее значение после сохранения (или что-то лучше?) В CakePHP

Я строю систему рейтинга, где пользователь может оценить что-то от 1 до 5 звезд.

Мне было интересно, есть ли способ автоматически рассчитать все оценки конкретного элемента (из таблицы рейтингов, где model='x' и foreign_key='y') на afterSave или что-то подобное.

Я могу сделать это в Rating_controller просто отлично... просто подумал, что это может быть более идеальным, чтобы сделать это автоматически в модели. Кто-нибудь может указать мне правильное направление для этого?

Мне очень хотелось бы услышать, что в CakePHP есть какая-то настройка ассоциации, которая позволяет ему сделать это для вас - что-то вроде:

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

Но - я уверен, что многого просят:)

2 ответа

Решение

Если вы хотите сохранить среднее значение в поле в таблице элементов, то 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, чтобы увидеть, как он структурирован, но я думаю, что понял это правильно.

Мне нужно написать и ответить, потому что я пока не могу комментировать.

Итак, ваши (например) рестораны имеют много рейтингов? Попробуйте VirtualField в модели ресторанов, где вы рассчитываете рейтинг каждый раз, когда рестораны выбираются из базы данных. Там может быть необходимость для GROUP BY, как упомянуто ypercube, если вам нужно использовать AVG().

Другие вопросы по тегам