require 'active_record' # This module extends ActiveRecord::Base to provide the # .first_after_created_at(date) and .first_after_id(id) functions module FirstAfterCreatedAt def first_after_created_at(date) first = select(:id, :created_at).first last = select(:id, :created_at).last jump_size = (last.id - first.id) / 2 best = _best(last, _best(first, nil, date), date) center = _first_after_id(first.id + jump_size) while jump_size != 0 jump_size /= 2 direction = center.created_at < date ? 1 : -1 # moving forward or backward new_center = _first_after_id(center.id + jump_size * direction) best = _best(new_center, best, date) center = new_center end find(best.id) if best end def _best(center, best, date) distance = center.created_at - date if distance >= 0 && (!best || distance < (best.created_at - date)) center else best end end def _first_after_id(id) select(:id, :created_at).where('id >= ?', id).order('id asc').first end end ActiveRecord::Base.send(:extend, FirstAfterCreatedAt)