Skip to content

Instantly share code, notes, and snippets.

@thiagoa
Created July 24, 2026 14:42
Show Gist options
  • Select an option

  • Save thiagoa/4902fe5aee424a6be391c33b86e3a5b3 to your computer and use it in GitHub Desktop.

Select an option

Save thiagoa/4902fe5aee424a6be391c33b86e3a5b3 to your computer and use it in GitHub Desktop.
Making has_one work efficiently with a lateral join (hacky but functional)
# Making has_one work efficiently with a lateral join
#
# The naive has_one with an ordering scope loads all matching rows
# and discards all but the most recent per user in Ruby. This hack
# makes the filtering happen at the SQL level.
#
# The trick: alias the users table as user_statuses so that Rails'
# preloader filters the users table instead of the user_statuses
# table before the lateral join runs. Without the aliasing trick,
# Rails would filter on the join table's user_id, so it would need
# to run the lateral join for every user in the table and then
# discard the ones not in the filter list.
class User < ApplicationRecord
has_one :current_status, -> {
lateral = UserStatus
.from("user_statuses AS us")
.where("us.user_id = user_statuses.user_id")
.order("us.created_at DESC, us.id DESC")
.limit(1)
.select("us.*")
# "user_statuses" here is actually the users table in disguise.
# Rails' preloader adds WHERE "user_statuses"."user_id" IN (...)
# which filters users before the lateral join runs.
from("(SELECT id AS user_id FROM users) AS user_statuses")
.joins("JOIN LATERAL (#{lateral.to_sql}) lateral_result ON true")
.select("lateral_result.*")
}, class_name: "UserStatus"
end
# Usage (works with eager loading):
#
# users = User.includes(:current_status).limit(15)
# users.each { |u| u.current_status&.status }
#
# Why we don't recommend it:
#
# It's too clever and coupled to Rails internals. It works, and
# it's unlikely to break, but it's not something we'd want to
# maintain in a production codebase.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment