Search code examples
ruby-on-railsrubyimageratingrating-system

Ruby on rails display star images for the rating system


I have a simple rails application where a user can leave a rating for a product and at the minute I have it so that the average rating is displayed on the index page, so for the book Animal Farm if there are the ratings: 1, 3, 5 the index will display 3 for that book. But what I want to do is replace the number displayed with stars, so rather than showing "star rating: 3" it will show "star rating:" then three star images. Is there a quick and simple way of doing this?

/views/products/index.html.erb:

<div id="star-rating">
        <% if not product.no_of_stars.blank? %>
          Star rating: <%= product.no_of_stars %>
        <% else %>
          <%= link_to 'Please add a Review',{ controller: 'reviews', action: 'new', id: product.id } %>
        <% end %>
      </div>

/models/product.rb:

def no_of_stars
    self.reviews.average('no_of_stars')
end

I also need to know where to save the image of a star and how to select that star to be displayed, so far I have it in the /app/assets/images directory. I need to do this purely in ruby without java.

Can someone please help, I am fairly new to ruby so could do with a complete breakdown of what to do? Thank you for reading.


Solution

  • You can do this with a helper. In case you need the stars in different models you can add a helper in the file app/helpers/application_helper.rb (I use '*' as a representation for a star):

    module ApplicationHelper
    
      def render_stars(value)
        output = ''
        if (1..5).include?(value.to_i)
          value.to_i.times { output += '*'}
        end
        output
      end
    
    end
    

    Your refactored view would look like this:

    <div id="star-rating">
      <% if product.no_of_stars.blank? %>
        <%= link_to 'Please add a Review',{ controller: 'reviews', action: 'new', id: product.id } %>
      <% else %>
        Star rating: <%= render_stars(product.no_of_stars) %>
      <% end %>
    </div>