Eric
Eric

Reputation: 793

How do you Display Avarage Rating in index page?

I'm trying to display average ratings for jobs on my index page, it works perfectly fine on my show page

but on my index page the stars are there but are blank, how do i get them to display on my index page?

My Show Page:

    <h4>Average Rating</h4>
<div class="average-review-rating" data-score=<%= @average_review %>></div>
<span class="number-of-reviews">Based on <%= @job.reviews.count %>  reviews</span>
</div>
    </div>

<script>

$('.review-rating').raty({
        readOnly: true,
        score: function() {
            return $(this).attr('data-score');
        },
        path: '/assets/'
    });

    </script>

    <script>
        $('.average-review-rating').raty({
            readOnly: true,
            path: '/assets/',
            score: function() {
                return $(this).attr('data-score')
            }
        });
    </script>

Jobs Show controller

def show


        if @job.reviews.blank?
            @average_review = 0
        else
        @average_review = @job.reviews.average(:rating).round(2)

        end

    end

My Index Page:

 <% @jobs.each do |job| %>
        <%= link_to job.title, job_path(job) %></h4>
        <%= job.category %></p>
        <%= job.city %>
        <div class="average-review-rating" data-score=<%= average_review %>></div>   
        <span class="number-of-reviews">Based on <%= job.reviews.count %>  reviews</span>               
            </div>
         </div>
       <% end %>

        <script>
            $('.average-review-rating').raty({
                readOnly: true,
                path: '/assets/',
                score: function() {
                    return $(this).attr('data-score')
                }
            });
        </script>

Upvotes: 1

Views: 532

Answers (2)

3limin4t0r
3limin4t0r

Reputation: 21130

You can fetch these results like so:

def index
  @jobs = Job.all
  @average_reviews = Review.where(job_id: @jobs)
                           .group(:job_id)
                           .average(:rating)
                           .transform_values { |rating| rating.round(2) }
end

This will return a hash with job ids as keys and the average rating as value (rounded to 2 decimals). To access these average ratings you can do the following in your index view:

@jobs.each do |job|
  average_review = @average_reviews[job.id]
end

The above code only makes 2 SQL calls, 1 for fetching your jobs and 1 for fetching all average reviews for all the fetched jobs. Keep in mind that if a job has no reviews. When fetching the average rating from the hash the value nil is returned.

Upvotes: 0

Mark
Mark

Reputation: 6455

In your show page, you have @average_review defined. I'm guessing this was done in your jobs controller in the show action.

In your index page, you will need to calculate the average rating for each job as you are iterating through them. You can do this the same way you defined @average_rating. If you are defining your @average_rating in the show action as:

@average_rating = job.reviews.sum('score') / job.reviews.count

You will need to either define this method in the model (the better option), so something like:

app/models/job.rb

def average_review
  reviews.sum('score') / reviews.count
end

Then in your index page:

<div class="average-review-rating" data-score=<%= job.average_review %>></div>

The other option is to set a variable for each object on the index page itself, less work but probably not as neat:

<% @jobs.each do |job| %>
  <%= link_to job.title, job_path(job) %></h4>
  <%= job.category %></p>
  <%= job.city %>
  <% average_review = job.reviews.sum('score') / job.reviews.count %>
  <div class="average-review-rating" data-score=<%= average_review %>></div>   
  <span class="number-of-reviews">Based on <%= job.reviews.count %>  reviews</span>               
      </div>
   </div>
 <% end %>

EDIT:

In your app/models/job.rb

def average_review
  reviews.blank? ? 0 : reviews.average(:rating).round(2)
end

And index.html.erb

<div class="average-review-rating" data-score=<%= job.average_review %>></div>

Upvotes: 1

Related Questions