Ignoring Rails for a moment, what you do in SQL is a lot of solutions . I would choose either DISTINCT ON or LEFT OUTER JOIN LATERAL . Here's what it looks like in Rails:
scope :closest, -> { select("DISTINCT ON (parent_id) events.*"). order("parent_id, date ASC") }
This will give you child objects . (You probably also want a condition to exclude strings without parent_id .) From your own decisions, this looks like what you want. If instead you want parent objects , with an extra child attached, use a side join. It is a little trickier to switch to ActiveRecord. If this is acceptable for this in two queries, it looks like it should work (adhering to DISTINCT ON ):
has_one :closest_child, -> { select("DISTINCT ON (parent_id) events.*"). order("parent_id, date ASC") }, class_name: Event, foreign_key: "parent_id"
Then you can say Event.includes(:closest_child) . Again, you probably want to filter out all non-parents.
source share