active_record_as_batches.rb 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. # https://github.com/telent/ar-as-batches
  3. # TODO: Should be reconsidered with rails 6.1 because then
  4. # find_each might be able to handle order as well
  5. # e.g. Ticket::Priority.order(updated: :desc).find_each... is not possbile atm with find_each
  6. module ActiveRecord
  7. module AsBatches
  8. class Batch
  9. def initialize(arel, args)
  10. @offset = arel.offset || 0
  11. @limit = arel.limit
  12. @size = args[:size] || 100
  13. return if !@limit || (@limit > @size)
  14. @size = @limit
  15. end
  16. def get_records(query)
  17. query.offset(@offset).limit(@size).all
  18. end
  19. def as_batches(query, &)
  20. records = get_records(query)
  21. while records.any?
  22. @offset += records.size
  23. records.each(&)
  24. if @limit
  25. @limit -= records.size
  26. if @limit < size
  27. @size = @limit
  28. end
  29. return if @limit.zero?
  30. end
  31. records = get_records(query)
  32. end
  33. end
  34. end
  35. def as_batches(args = {}, &)
  36. Batch.new(arel, args).as_batches(self, &)
  37. end
  38. end
  39. class Relation
  40. include AsBatches
  41. end
  42. end