Most recent record

We have two models Sensor and Reading.

class Sensor < ApplicationRecord
  has_many :readings
end
class Reading < ApplicationRecord
  # integer :status
  # float :value
  # integer :sensor_id
end

And we want to select the latest reading for a sensor. We can do

Sensor.find(params[:id]).readings.last # default ordering id DESC

Now if we have 10 sensors and every sensor has over 10,000 readings and we want to display the latest reading for all the sensors.

Doing this will generate n+1 queries

# controller
@sensors = Sensor.all

# view
@sensors.each do |sensor|
  sensor.reading.last
....

and we don’t to want eager load all 10K records

Sensor.includes(:readings)

Instead we can create a has_one association in the Sensor model

# Note: DISTINCT ON is only available in Postgres

class Sensor < ApplicationRecord
  has_many :readings
  has_one :latest_reading, -> { select("DISTINCT ON(sensor_id) *").order("sensor_id, id DESC") }, class_name: 'Reading'
end

Now we can eager load only the latest readings 😉

Sensor.includes(:latest_reading)

Leave a Reply

Your email address will not be published. Required fields are marked *