Рейтинг

Доброе утро всем, дайте пожалуйста РАБОЧИЙ пример рейтинга с кодом контроллера. Перерыл весь гугль, но зараза не хочет сохраняться значение рейтинга в БД и все тут :(

Код виджета в view.php


$this->widget('CStarRating',array(

	'name'=>'rating', // имя переменной в форме

	'maxRating' => 5, // максимальное значение

	'minRating' => 1, // минимальное значение

	'value' => $rating, // текущее установленное значение

	'allowEmpty' => false, // убрать  кнопку 'cancel'

	'readOnly' => $userVoted, // если true, то доступно только для чтения

 

        /** После нажатия на рейтинг посылаем выбранное значение на сервер, а затем делаем виджет readOnly */

        'callback'=>' // что делать при нажатии

	function(){

		$.ajax({

		type: "POST",

		url: "'.Yii::app()->createUrl('film/StarRatingAjax').'",

		data: "id='.$model->id.'&rate=" + $(this).val(),

		success: function(msg){

		$("#rating > input").rating("readOnly", true);

		alert("Спасибо!");			

		}})}'

	 ));

Код в контроллере


public function actionStarRatingAjax() {

        if (Yii::app()->request->isAjaxRequest) {

            $rating = $this->loadModel($_POST['id']);

            $rating->rating = $_POST['rate'];

            $rating->save();

			//return $rating;

            } 

        }

Первая часть вроде как работает, а вот переданное значение в БД писаться не хочет :unsure:

Помогите добить, методом проб и ошибок id вытаскивается и нужное значение пишется в БД. Но теперь другая проблема - записанное значение не выбирается из БД, т.е. звезды не горят, не одной :blink:

Код view.php


$this->widget('CStarRating',array(

	'name'=>'rating', // имя переменной в форме

	'maxRating' => 5, // максимальное значение

	'minRating' => 1, // минимальное значение

	'value' => $rating, // текущее установленное значение

	'allowEmpty' => false, // убрать  кнопку 'cancel'

	'readOnly' => $userVoted, // если true, то доступно только для чтения

 

        /** После нажатия на рейтинг посылаем выбранное значение на сервер, а затем делаем виджет readOnly */

        'callback'=>' // что делать при нажатии

	function(){

		$.ajax({

		type: "POST",

		url: "'.Yii::app()->createUrl('film/StarRatingAjax').'",

		data: "id='.$model->id.'&rate=" + $(this).val(),

		success: function(msg){

		$("#rating > input").rating("readOnly", true);

		alert("Спасибо!");			

		}})}'

	 ));

Код контроллера


public function actionStarRatingAjax() {

        if (Yii::app()->request->isAjaxRequest) {

			// $model = Film::model()->findByPk($this->id);

			 $model = $this->loadModel($_POST['id']);

            $model->rating = $_POST['rate'];

            $model->save();

           } 

        }

Разобралси, всем спасибо за помощь :unsure: Подскажите пожалуйста как вывести среднее значение рейтинга, я так понял после того как проголосовал новый пользователь, старый голос затирается ? :blink:

Вам нужно создать еще одну модель (и таблицу в базе данных), скажем, FilmRate, чтобы хранить в ней значения голосов пользователей.

Структура следующая: rate_id (primary), user_id, film_id, value.

Когда пользователь голосует, создаем новую запись в этой таблице.

При в контроллере проверяем существует ли запись с id данного пользователя в таблице и записываем этот результат в $userVoted, затем выводим при загрузке виджета. Примерно так:


$criteria = new CDbCriteria();

$criteria->condition = 'user_id='. Yii::app()->user->id 

                       . ' AND film_id=' . $film->film_id; //$film - экземпляр модели Film

$userVoted = FilmRate::model()->exists($criteria);



Средний рейтинг фильма $rating ищем с помощью такого запроса:


"SELECT AVG(value) FROM tbl_film_rate WHERE film_id=" . $film->film_id; 

Можно использовать более простой способ:

Хранить в таблице с каждым фильмом значение среднего рейтинга и количества проголосовавших.

После каждого нового проголосовавшего перезаписывать средний рейтинг и количество проголосовавших.

Примерно так:




$film->rating = ($film->rating*$film->count+$newVoteValue)/($film->count+1);

$film->count++;

$film->save();



Записываем результат в базу данных.

Но тогда отследить, какой пользователь уже голосовал будет невозможно.

Спасибо, что откликнулись и спасибо за дельные советы :) Что-то в этом роде и создал в своем творении, правда если честно, за основу взял один вариант с этого же форума и допилил под свои запросы. Все отлично работает, только вот беспокоит один момент - данные передаются путем get запроса, если делать через post отказывается выбирать id записи. Хотя если жестко задать id, то сохранение происходит без проблем :blink: