Reputation: 103
I've used Ruby on Rails and Raty.js to create a rating system for my pins. You can see the average rating in the individual Show pages for each pin. I'd like to incorporate that into my index file. Currently, the rating that is showing for all pins in the index is the average rating of the first pin.
Note: I'm using Haml for the index file, but if you could provide an answer in basic html, that'll be fine.
index.html.haml:
.panel-footer
.btn-group.pull-left
%div{class: "srating", dscore: @avg_review }
:javascript
$('.srating').raty({
path: '/assets/',
readOnly: true,
score: function() {
return $(this).attr('dscore');
}
});
pins_controller.rb:
class PinsController < ApplicationController
before_action :find_pin, only: [:show, :edit, :update, :destroy, :upvote, :un_upvote]
before_action :authenticate_user!, except: [:index, :show]
def index
@pins = Pin.all.order("created_at DESC").paginate(page: params[:page], per_page: 7)
for singlepin in @pins
@stars_reviews = StarsReview.where(pin_id: singlepin.id)
if @stars_reviews.blank?
@avg_review = 0
else
@avg_review = @stars_reviews.average(:rating).round(2)
end
end
end
Upvotes: 0
Views: 282
Reputation: 10416
It's actually showing the average rating for the last pin.
for singlepin in @pins
@stars_reviews = StarsReview.where(pin_id: singlepin.id)
if @stars_reviews.blank?
@avg_review = 0
else
@avg_review = @stars_reviews.average(:rating).round(2)
end
end
Each loop here is just setting the one variable to the new value.
So either add an average rating attribute on pin and update it everytime someone rates it.
Or make the variable an array:
@avg_reviews = []
for singlepin in @pins
@stars_reviews = StarsReview.where(pin_id: singlepin.id)
if @stars_reviews.blank?
@avg_reviews << 0
else
@avg_reviews << @stars_reviews.average(:rating).round(2)
end
end
Then output as you loop over the pins
<% @pins.each_with_index do |pin, i| %>
%div{class: "srating", dscore: @avg_reviews[i] }
<% end %>
Or you could allow an attribute on pin that you set
class Pin
attr_accessor :avg_review
end
for singlepin in @pins
@stars_reviews = StarsReview.where(pin_id: singlepin.id)
if @stars_reviews.blank?
singlepin.avg_review = 0
else
singlepin.avg_review = @stars_reviews.average(:rating).round(2)
end
end
Then access it in the view
<% @pins.each do |pin| %>
%div{class: "srating", dscore: pin.avg_review }
<% end %>
Upvotes: 1