Say I have a books table that has id and name columns and a has_many book_ratings association. The book_ratings table has id, rating, rating_date, and book_id columns and belongs_to :book. I'm displaying the books in a table with 3 columns: the books name, the highest rating for the book, and the most recent rating for the book. I want each column sortable and I'm using the Pagy gem for pagination. I want to make a single call to each table to avoid N+1.
I made this query which includes the max_rating and sorts by max_rating:
@pagy, @books = pagy(
Book.joins(:book_ratings)
.select('books.*,MAX(rating) as max_rating')
.order('max_rating')
.group('books.id')
)
With each book record, I can call book.max_rating to display the max_rating in the table. I cannot think of a way to also include the rating with the latest date and sort the records by that rating. I know I can use MAX(rating_date) to get the date of the book_rating with the most recent date, but I need a way to include the rating value of the book_rating with the latest date and also be able to order the book records by those values.
Any ideas?
To get this to work, I ended up using a select method and then chaining two joins methods. Here's what I ended up using:
Calling
.to_sqlon that query gives this SQL:When iterating through this collection, latest_rating and highest_rating can be called on each object and provides the value from the rating column for either. It can also be used with
.order('latest_rating asc')(or desc) or.order('highest_rating asc')(or desc)