# rails' find_each and find_in_batches do not respect order on a scope
# this implementation is inspired by:
# https://github.com/telent/ar-as-batches
require 'active_record'
module ActiveRecord
  module FindEachOrdered
    def find_each_ordered(args={},&blk)
      batch_size=args[:batch_size] || 1000
      offset=arel.offset || 0
      limit=arel.limit
      if limit && (limit < batch_size) then batch_size = limit end
      records = self.offset(offset).limit(batch_size).all
      while records.any?
        offset += records.size
        records.each { |r| yield r }
        if limit then
          limit -= records.size
          if (limit < batch_size) then batch_size = limit end
          if limit.zero? then
            return
          end
        end
        records = self.offset(offset).limit(batch_size).all
      end
    end
  end

  class Relation
    include FindEachOrdered
  end

  class Base
    class << self
      # use find_each since order is not important if called directly on class
      alias_method :find_each_ordered, :find_each
    end
  end
end
