Listing number of user reviews

Hi Alex For the review app - how would one show the total number of reviews a user has submitted on the restaurant show page (under their name on each review). Thanks Graham

Posted almost 4 years ago by Graham Schwikkard
Posted almost 4 years ago by Alex Yang

Since we've set up an association between Users and Reviews (a User has many Reviews), we can use '@user.reviews' to pull all the reviews that a specific user has written. Note that '@user' must be defined in your controller file. Then, to count the number of reviews, we can just do '@user.reviews.count'. Add that in where you need it in your view page and you should be all set.

1
Posted almost 4 years ago by Gschwikk

Thanks so much Alex, I knew the data was setup right, just still learning how to access it. I can get the show to work with a static user id but after a few attempts I can't figure out what exactly to put in the controller to return the user for each review. With all my attempts, I can only get the first review's user to be used (and so it just show's that user's number of reviews under each review, not whoever wrote the review).

I think I should be using @user = Review.find(id: @review.id).user but I'm not sure how to get @review to be the active review being displayed. Thanks

1
Posted almost 4 years ago by Alex Yang

I understand what you mean. In situations like these, where you need @review to be dynamic and reflect the review being displayed, it's best to do this directly through the view (not from the controller). Let me explain how that would work in this case:

In our controller, we first define '@reviews'. The way we've defined it in the Yelpdemo course is as follows (but it doesn't necessarily need to be defined this way):
@reviews = Review.where(restaurant_id: @restaurant.id).order("created_at DESC")

Then in our view, we want to display each of the reviews in the '@reviews' variable, so we use a loop:
<% @reviews.each do |review| %>
...
<% end %>

Keep in mind that while we're in the loop, we'll use 'review' (not '@review' or '@reviews') to refer to the active review. Make sure you understand why this is - let me know if you need any clarification.

Underneath each review, we want to display 1) the name of the user who wrote the review and 2) the total number of reviews that user has written. Let's tackle these one by one:

1) As I mentioned above, since we have already set up the Users/Reviews association (a User has many Reviews), we can use 'review.user' to retrieve the user who wrote the active review. So we can use the following to pull the user's first and last name:
<%= "#{review.user.first_name.capitalize} #{review.user.last_name.capitalize[0]}." %>

2) Similarly, since we've set up the Users/Reviews association, we can use '@user.reviews' to retrieve all the reviews written by '@user' (I'm assuming that the variable '@user' stores the user whose reviews we want to pull). However, in this case the specific user we want is 'review.user' so we will use that to replace '@user'. So to retrieve all the reviews of the user who wrote the active review, we use 'review.user.reviews'. I know the syntax is a little confusing, but break it down piece-by-piece and it should make sense. Finally, if we just want the total number of reviews, we'll use the count method to get our final result: 'review.user.reviews.count'.

2
Posted almost 4 years ago by Gschwikk

Thanks for the detailed explanation - it makes complete sense. I didn't realise we could use 'review.user.reviews', otherwise, I might have tried that. I know understand it's because of the has_many relationship.

It works no problem now - thanks :-)

1