Eu lutei um pouco com exatamente o mesmo problema em um aplicativo com uma grande quantidade de linhas e depois de tentar várias soluções novas, como junções laterais e subconsultas, a solução com melhor desempenho e de longe mais simples foi apenas adicionar uma chave estrangeira à tabela que aponta para a linha mais recente e use um retorno de chamada de associação (ou um db trigger ) para definir a chave estrangeira.
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 })
Realmente brilha se a quantidade de registros associados for enorme como no meu caso, pois você pode carregar o registro mais recente sem os problemas de memória que ocorrem se você carregar todo o
has_many
Associação.