/ Tags: RAILS-CODE / Categories: SOLUTIONS

Query Records Created Or Updated In The Last N Hours In Rails

Dashboards, digest emails, and sync jobs all need “what changed recently”. Rails’ duration helpers plus a beginless or endless range make this readable and, crucially, index-friendly.

Description

3.hours.ago.. is an endless range, and ActiveRecord turns it into >= ? — which a B-tree index on the timestamp can use. Writing where("updated_at > ?", ...) works too but loses the composability of a hash condition. Prefer a range over Time.current - 3.hours arithmetic; the duration helpers handle DST and month lengths correctly. Always store and compare in UTC. Mixing a local Time.now with a UTC column is the most common source of off-by-hours bugs here. Wrap the common cases in scopes so the intent is named rather than recomputed.

Sample input:

  Order.updated_within(6.hours)


Sample Output:

  SELECT orders.* FROM orders WHERE orders.updated_at >= '2026-05-17 03:00:00'

Answer

  class Order < ApplicationRecord
    scope :created_within, ->(duration) { where(created_at: duration.ago..) }
    scope :updated_within, ->(duration) { where(updated_at: duration.ago..) }

    scope :updated_between, ->(from, to) { where(updated_at: from..to) }

    scope :stale, ->(duration) { where(updated_at: ...duration.ago) }
  end

  Order.updated_within(6.hours)
  Order.created_within(1.day).count
  Order.stale(30.days)                     # not touched in a month

  # Explicit window
  Order.updated_between(2.days.ago, 1.day.ago)

  # Calendar-relative rather than rolling
  Order.where(created_at: Time.current.all_day)
  Order.where(created_at: Date.current.beginning_of_week..)

  # Records changed since a stored checkpoint — the sync-job pattern
  last_run = SyncCheckpoint.last_run_at
  Order.where(updated_at: last_run..).find_each do |order|
    Warehouse.push(order)
  end

  # Index this, or the scan gets expensive
  # add_index :orders, :updated_at

Learn More

cdrrazan

Rajan Bhattarai

Full Stack Software Developer! 💻 🏡 Grad. Student, MCS. 🎓 Class of '23. GitKraken Ambassador 🇳🇵 2021/22. Works with Ruby / Rails. Photography when no coding. Also tweets a lot at TW / @cdrrazan!

Read More