Adding a Star Rating system to your application - Step 1 - Generating BREAD for Star Ratings

Many modern web-based software application are heavily dependent on star rating systems. In a typical scenario users in an online marketplace for a product or service have the ability to rate the product, service or their experience. As more and more ratings are added the "wisdom of the crowd" takes over. Where there are many thousand ratings and the service offered is averaging a 98% rating, users can be almost certain of receiving a positive experience.

In order to deliver this kind of functionality an application needs the following:

  • Ability for the user to rate the product, service or experience using stars. The rating can be out of any number but typically is from 1 to 5 stars or 1 to 10 stars.
  • Ability for other users who might wish to use the service to see an average of all the previous ratings and understand how many ratings that is based on. A rating of 5 stars where only 3 reviews have been received is not nearly as useful as a rating of 4.2 stars where 10 thousand reviews have been received.
  • The ability for the user to drill down on the average in order to see the explanations behind the ratings. Many modern systems also allow the supplier to provide a response to give their side of the story. On the basis of a minimum viable product approach, we will stick to providing a list of all the previous reviews.

The first of these posts will describe how to extend the tennis club application to allow users to rate each tennis court they play on out of 5 stars and to provide an explanation for why they liked or didn't like the court. Subsequent posts will describe how to display an average rating for each court and how to drill down on the information behind the averages. Given that there can be many ratings for each court we will need a new database table to store all of the information related to court ratings. If you don't already have the tennis club database you can get the script to create it from the 3rd post in the getting started section. Once you have created that database you can create the courtRating table using the following database script:

drop table if exists courtRating;
create table courtRating (
   id int auto_increment,
   rating int,
   comment text,
   created_at datetime,
   updated_at datetime,
   deleted_at datetime,
   courtid int,
   primary key(id),
   foreign key(courtid) references court(id)
);

Now scaffold the new table using the Infyom scaffold command in the CLI as follows

php artisan infyom:scaffold courtrating --fromTable --tableName=courtrating

Now re-scaffold the court table in order to pick up on the hasMany relationship between court and court rating. Use the following command in the CLI

php artisan infyom:scaffold court --fromTable --tableName=court

In order for users to rate a specific court we need them to indicate which court they are rating. As courtid is a foreign key of courtRating the scaffolder will have generated the courtid and it will be present on the create view. This allows the user to fill in the courtid they wish to rate when filling in the form as follows.

The problem with this approach is that it's clunky and error prone. If the user fills in a court id that does not exist the user will receive an integrity constraint violation. You cannot rate a court that does not exist. In previous examples we have improved the scaffolded form by introducing a dropdown list which looks-up the table the foreign key is pointing at and generates a list of possible correct options.

In this example, rather than using the dropdown approach we are going to put the courtid into the flow of the use case. On the courts page where there is a list of courts there are a number of things we can do to each court. So far these options include show, edit and delete. These options work by passing the courtid selected by the user to the relevant controller function.

Place this additional line in the table of the create view as follows

Leave a Reply