star rating rails 4 jquery ajax javascript raty

1.6k views Asked by At

I am attempting to follow this tutorial and I am getting stuck: Adding a 5 star ratings feature to a Rails 4 model.

Im a begginer with javascript and ajax so I spent a few hours learning how ajax works with javascript. I believe the problem has to do with where the average_rating method is (rails problem?).

def average_rating
  ratings.sum(:score) / ratings.size
end 

Currently I have followed the tutorial exactly how it says, while replacing comment with review. In the tutorial it says to define the average_rating in the comment model (mine is in the review model), and I am not sure why I would do that.

Also I have added this (not sure if It belongs in the current controller or if it belongs in rating controller):

#this is the controller used for the view which displays the stars
def page
  @rating = Rating.where(review_id: @review.id, user_id: @current_user.id).first
  unless @rating
    @rating = Rating.create(review_id: @review.id, user_id: @current_user.id, score: 0)
  end
end

When I try to load the page here is the error I get: ZeroDivisionError below it says divided by 0 and it highlights this line score: <%= @review.average_rating %>,

UPDATE When I delete this script from the view which has the average_rating, the stars show for my_rating. So something is messing up with the average part:

<script> #did not delete this line
  $('#star').raty({
    readOnly: true,
    score: <%= @review.average_rating %>,
    path: '/assets'
  });

Deleted part^^^

1

There are 1 answers

0
Nuriel On

Basically, i would love to get more info, but here are some pointers that might help:

  • make sure the relation is working: make sure you have has_many :ratings for the user/review and 'belongs_to :user/:review' for the ratings. other direction- are you getting the ratings in a controller method? if so, consider changing it to @ratings.
  • use first_or_XXXX - this is a great rails option to save conditional instantiation. there is first_or_create that would do exactly what you did:

Rating.where(review_id: @review.id, user_id: @current_user.id).first_or_create do |rating| rating.score = 0 end

  • finally, ratings.size, will not update after create, which might explain the zero devision. read more in this question's selected answer and comments. Therefore, it's recommended to use count (will check on the db, so only saved ratings will be counted) or length (i.e. user/review.ratings.length which will count also built (not saved) objects.

hope that helps.