问题
I'm setting up a simple ruby/rails app where users can review albums. On an album's show page I average all the user reviews associated with that album through this code in my albums controller
def show
@album = Album.find_by_id(params[:id])
if @album.reviews.present?
@ratings = Review.where(album_id: @album).average(:rating).truncate(2)
else
render 'show'
end
end
This gives me an average rating for each album. On my home page (routed through a different controller) I want to display the top 7 albums with the highest average rating.
What I originally did was put this code into the separate home page controller:
@albums = Album.all
@ratings = @albums.each {|album| album.reviews.average(:rating).to_f}
@ranked_ratings = @ratings.sort_by {|rating| rating}
@top_seven = @ranked_ratings.reverse[0...7]
I thought I found the solution until I realized all I'm showing is the last 7 albums entered into the database.
Going back to the drawing board I have been able to get an array of all the albums (each element within the array is a list of reviews associated with that album) with this code in my controller:
@albums = Album.all
@ratings = @albums.collect {|album| album.reviews}
I'm stuck at this point trying to figure out how to cycle through @ratings and find the average rating for each album_id, then order those records by the highest average rating and display them in a view.
回答1:
try @albums = Album.joins(:reviews).select("album.id, avg(reviews.rating) as average_rating).group("album.id").order("average_rating DESC")
I extrapolated it from: Ruby on Rails: Order users based on average ratings with most reviews?
Update:
try this instead: @albums = Album.joins(:reviews).select("*, avg(reviews.rating) as average_rating").group("albums.id").order("average_rating DESC")
来源:https://stackoverflow.com/questions/20852887/how-to-display-highest-rated-albums-through-a-has-many-reviews-relationship