Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails & Active Record: Create a scope to get the most recent child

A User has_many Books. I want to add a scope to Books that only returns the most recent (created_at) book for each user_id. Something that groups the books by user_id and only gets the most recent for each user_id ?

To clarify, I could technically do this:

User.all.each { |user| user.books.first }

But I'd like to do it with a clean Active Record query.I'm having a lot of trouble figuring it out, but I imagine the solution isn't too complicated.

like image 981
Jackson Cunningham Avatar asked Nov 25 '25 14:11

Jackson Cunningham


1 Answers

The easiest way to do this is to create a scope on books that, using a subquery, only selects books that are the latest ones owned by their user:

class Book < ActiveRecord::Base
  belongs_to :user

  scope :most_recent, -> {
    where('NOT EXISTS(SELECT 1 FROM books b2 WHERE b2.user_id = books.user_id AND b2.created_at > books.created_at)')
  }
end

This is just one of many options, but it's likely the most re-usable as you can join this relation onto others without worrying about your aggregations conflicting.

like image 116
Robert Nubel Avatar answered Nov 27 '25 05:11

Robert Nubel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!