Yii Framework Forum: Рейтинг - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Рейтинг Rate Topic: -----

#1 User is offline   melomaniac 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 174
  • Joined: 14-January 13

Posted 09 March 2013 - 07:58 PM

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

Код виджета в 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:
0

#2 User is offline   melomaniac 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 174
  • Joined: 14-January 13

Posted 09 March 2013 - 10:31 PM

Помогите добить, методом проб и ошибок 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();
           } 
        }

0

#3 User is offline   melomaniac 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 174
  • Joined: 14-January 13

Posted 09 March 2013 - 10:41 PM

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

#4 User is offline   Extj 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 9
  • Joined: 19-June 12

Posted 10 March 2013 - 09:28 AM

Вам нужно создать еще одну модель (и таблицу в базе данных), скажем, 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();

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

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

#5 User is offline   melomaniac 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 174
  • Joined: 14-January 13

Posted 10 March 2013 - 04:04 PM

View PostExtj, on 10 March 2013 - 09:28 AM, said:

Вам нужно создать еще одну модель (и таблицу в базе данных), скажем, 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:
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users