Ho lottato un po' con lo stesso identico problema in un'applicazione con un'enorme quantità di righe e dopo aver provato varie nuove soluzioni come join laterali e sottoquery, la soluzione con le prestazioni migliori e di gran lunga più semplice è stata semplicemente aggiungere una chiave esterna alla tabella che punta all'ultima riga e utilizzare un callback di associazione (o un db trigger ) per impostare la chiave esterna.
class AddLatestEmploymentToEmployees < ActiveRecord::Migration[6.0]
def change
add_reference :employees, :latest_employment, foreign_key: { to_table: :employments }
end
end
class Employee < ActiveRecord::Base
has_many :employments, after_add: :set_latest_employment
belongs_to :latest_employment,
class_name: 'Employment',
optional: true
private
def set_latest_employment(employment)
update_column(:latest_employment_id, employment.id)
end
end
Employee.joins(:latest_employment)
.where(employments: { status: :active })
Brilla davvero se la quantità di record associati è enorme come nel mio caso poiché puoi caricare ansiosamente l'ultimo record senza i problemi di memoria che si verificano se carichi l'intero has_many
associazione.