One Comment Per Category

Hey guys, i’m completely lost on this one.

I’m creating a project where you rate video-games from 1-10 in 5 different categories. These ratings will also be associated with 1 of 12 different platforms a game can work on. The table will contain these columns:

id

game_id

platform_id

create_user_id

create_time

overall

graphics

sound

gameplay

lastingApp

An example:

I choose to rate a game i played on my xbox, so i pick "XBOX 360" as the platform, whereafter i rate the game in the 5 different categories. The next time i visit that particular game on the website, i should be able to change my rating for the XBOX version (and not be able to submit a new one for XBOX), but at the same time be able to submit a new rating for the PS3 version of the game.

How can i achieve this?

This far i’ve written this in the GameController, but it’s clear that it need something more before it will work as i described above:




        $user_id=Yii::app()->user->getId(); 

	$game_id=$model->id;

        $rate=rating::model()->find("create_user_id=$user_id and game_id=$game_id"); 

        

        if($rate===null){

		$rating=new Rating;

		}

		else{

		$rating=$rate;

		}

		

		if(isset($_POST['Rating']))

		{

			$rating->game_id=$model->id;

			$rating->attributes=$_POST['Rating'];

			

			$valid = $rating->validate();

			if ($valid)

			{

			    $rating->save(false);

			    $this->redirect(array('index'));

			}

		}

Or is it even possible to do something like this?

Yes, it’s definitely possible. If I was writing this application, I would create a preFilter and verify the user/game/platform combination hasn’t already been submitted. I would also validate it in the model’s beforeSave method to prevent other controllers from violating the business rule.





class RatingFilter extends CFilter

{


    protected function preFilter($filterChain)

    {

        return $this->verifyRating();

    }


    /**

 	* Verifies if the user's rating is valid. The rating is

 	* considered valid if user, game, & platform are unique.

 	* @return boolean whether the rating is valid.

 	*/

    private function verifyRating()

    {

        $isValid = true;


        $userId = Yii::app()->user->getId();

        $gameId = $_POST['game_id'];

        $platformId = $_POST['platform_id'];

        

        $rating = Rating::model()->findByAttributes(array(

            "create_user_id" => $userId,

            "game_id" => $gameId,

            "platform_id" => $platformId));


        // a rating (game/platform) was found for the user so we need to prevent them from submitting another one

        if ($rating)

            $isValid = false;


        return $isValid;

    }


}

Matt

Thanks for your reply, but the main problem still is that this doesn’t allow the user to edit their ratings without only being able to rate the game on 1 platform.

If the user selects a platform (in the dropdown-list in the rating-form) that he/she hasn’t rated the game on, a new rating should be submitted. If however the user selects a platform in the dropdown-list that he/she has already rated the game on, the application should find those values and the user should be able to update them.

Perhaps some AJAX should be used in order to make it dynamic?

I think that you were on the right track with the code you posted. If result not found, create a new model, assign data and save. If record was found, set it as active model, change data(be sure that the scenario is update) and save it. Check for the combination waterloomatt provided.

Cheers

Yes, but these things is only looked for by the application before the page is loaded or after the user submits. I want it to decide wether to create or update a rating just after the user has chosen which platform he rates the game on, but before he submits. Kind of like if i enable AJAX-validation on a form to check and tell the user wether the username (as an example) has already been taken.

The filter should only be applied to actionCreate.

Sounds like what you’re looking for is an ajax call to load the rating form. In that case, separate your form logic into a new action so your ajax calls can access it.

  • [size=2]make an action (actionLoadRatingForm) and [/size]
  • [size=2]in that method, check to see if a rating has been submitted.[/size][list]
  • [size=2]If yes, load the Rating model and pass it to the form (render partial _rating_form)[/size]
  • [size=2]If no, create a new Rating model and pass it to the form[/size] (render partial _rating_form)

[/list]

I’m goin to look into how to create something like that then. Thanks for your help

[size=2]To be honest, I would get the functionality working without JS and then add it after to improve the UX. I’ve attached a screen shot of a possible layout that doesn’t rely on JS. The basic idea is to load [/size]available platforms [size=2]and restrict the platform drop down to those. Also, create a list of [/size]completed ratings [size=2]and give the user the ability to edit them. When editing a rating, you could then make an ajax call to populate the form. In my experience, dynamic drop downs can be slow. [/size]

3918

GameRating.png

Matt