|

A User hasMany Games and also hasMany Reviews

Users Can Add Games and Reviews

When we first started out creating our little games app, we set up a form to add games to the system. We also set up a form to add reviews for games in the system. We were able to establish the relationships between games and reviews. This was all done as a strictly guest based system as we had no user authentication system until just recently. Now that we have a user registration system in place, we need to find a way to associate users with both games and reviews. A user could submit one or more games to the site. A user could also submit one or more reviews to any given game. We can tackle the User to Game and Review relationships in this tutorial.


Update Migrations

Right now we have a games table and a reviews table in the database which hold all the information about, you guessed it, games and reviews! What is missing on those tables are a way to link a particular record to a particular user. To facilitate this, we need something like a user_id field on both of those tables. We can update those migrations and refresh now.


database/migrations/xxxx_xx_xx_xxxxxx_create_games_table


database/migrations/xxxx_xx_xx_xxxxxx_create_reviews_table

Time to refresh the migrations. As we know, we will lose all games, reviews, and now users out of our database when we do this. There are ways to set up a migration to alter a MySql table instead of drop it and rebuild it, but we don’t really need to worry about that here. So here goes nothing.
migrate and refresh the database


Update Models

In order to associate a User with a Game or Review, we need to update those models. They are each going to need a new method to attach a Game submission to a user, and a Review submission to a user. In other words, a game will belong to a user, and a review will also belong to a user. We will use the belongsTo() relation for this. Here are those updated models.


app/Game.php


app/Review.php

We can also update the User model as well. This is because a User can have many game submissions, and may also have many review submissions. For this, we will use the hasMany() relation.


app/User.php


Update Controllers

We are also going to need to update our controllers, and specifically we need to update the store() methods on them. This is because before, when we were storing a game or review in the database, we never accounted for the user that submitted the game or review. We didn’t need to include that before, because any anonymous person could just visit one of the forms, without any type of authentication in place, and submit a game or review. Now that we have a user registration system in place, we want to track which logged in user submitted which game or which review to the database. For this, we will need to account for the user_id of the authenticated (logged in) user when the store() method fires.


app/Http/Controllers/GamesController.php

Notice above that we are now storing the id of the logged in user into the user_id field of the games table before we save the model. We fetch the user id with auth()->id(). Very good.


app/Http/Controllers/ReviewsController.php

This update to the store() method is a little more curious. Recall that we had extracted a method to the Game model, and that is where we actually store the review using a relation. When we call addReview() here in the ReviewsController, we were passing the body of the add a review form via request(‘body’). We now also need to pass the user id as the second parameter, and that is exactly what we did via auth()->id(). Of course this means we must now also update the addReview() method on the Game model. Let’s go ahead and do that now.


app/Game.php

Nice! Notice the addReview() method is now accepting that second argument, which is then in turn passed as the second argument to the create() method as the second element in the array. Now the create() method makes use of mass assignment, and recall that we have already set body and game_id as fillable on the Review model. Well guess what, yes that’s right, we must now also add the field of user_id to the fillable property on the Review Model, otherwise this refactor above will fail when we go to add a review. We can update the Review Model like so now.


app/Review.php


Update Views

Ok! Most of the leg work is out of the way. We can now update our view files so that when a game is submitted, we will see the user that submitted it. In addition, any review added will also show which user submitted the review. First off though, let’s add a link in the navigation area for logged in users only, so that they can submit a new game.

Add a Submit Game link to navbar


resources/views/partials/navbar.blade.php

Show the user name for a submitted game when listing all games

When the user lists all games, we can now include the name of each user that submitted each game. We just need to update index.blade.php found in resources/views/games/index.blade.php and include a call to $game->user->name.


resources/views/games/index.blade.php

Show the user name for a submitted game, and the user name for a submitted review

We can now also update the resources/views/games/show.blade.php view to include the name of the user that submitted the game being shown in addition to showing the name associated with any reviews for that game. We can make use of $game->user->name to show the user that submitted a game, and $review->user->name to show the user who submitted a review. Here is how we can update the show.blade.php file to make this work.


resources/views/games/show.blade.php


Testing Adding Games and Reviews

We can now test logging in as a specific user, and submitting a game or review. We should find that $game->user->name will now show us which user submitted a game. For game reviews, $review->user->name should tell us which user wrote the review. In addition, auth()->user()->name will show us what user is currently logged in. We shall now log in as a user “Toad” and submit a game. Let’s see how this works.

toad submitted super mario bros

Bingo! We can now log out, then log in as user “Luigi” and leave a review on the game Super Mario Bros.
luigi leaves a review on the game todd submitted

Now we can log out, then log back in as “Mario” and also leave a review. At that point, we should see that we are logged in as Mario, that the game was submitted by Toad, there is one review by Luigi, and now we can add another review by Mario.
mario leaves his own game review


Users Can Add Games and Reviews Summary

How cool is this little app now?! In the beginning, of this series all we had was a couple of routes, and not much else. We’ve come a long way to the point of have users that can register, log in, log out, submit new games, and submit new reviews. As users submit games and reviews to the site, our Eloquent relations show us exactly which user submitted which game or review. Very cool!