I\'m struggling how to have Ruby on Rails do this query right... in short: to join on a has_many
relation but only via the most recent record in that r
One alternative is to use a LATERAL JOIN which is a Postgres 9.3+ specific feature which can be described as something like a SQL foreach loop.
class Employee < ApplicationRecord
has_many :employments
def self.in_active_employment
lat_query = Employment.select(:status)
.where('employee_id = employees.id') # lateral reference
.order(created_at: :desc)
.limit(1)
joins("JOIN LATERAL(#{lat_query.to_sql}) ce ON true")
.where(ce: { status: 'active' })
end
end
This fetches the latest row from employments and then uses this in the WHERE clause to filter the rows from employees.
SELECT "employees".* FROM "employees"
JOIN LATERAL(
SELECT "employments"."status"
FROM "employments"
WHERE (employee_id = employees.id)
ORDER BY "employments"."created_at" DESC
LIMIT 1
) ce ON true
WHERE "ce"."status" = $1 LIMIT $2
This is going to be extremely fast in comparison to a WHERE id IN subquery
if the data set is large. Of course the cost is limited portability.