prueba esto:
Character.find_by_sql("SELECT *, rank() OVER (ORDER BY points DESC) FROM characters")
debería devolverle objetos de carácter con un atributo de rango, como se documenta aquí . Sin embargo, esto puede no ser independiente de la base de datos y tiende a ensuciarse si pasa los objetos.
otra solución (costosa) es agregar una columna de rango a su tabla y hacer que una devolución de llamada vuelva a calcular el rango de todos los registros usando .order cada vez que se guarde o destruya un registro.
editar:
se puede ver otra idea adecuada para consultas de registro único aquí