Module: ActiveRecord::FindInBatchesWithOrder
- Included in:
- Relation
- Defined in:
- lib/ar-find-in-batches-with-order.rb,
lib/ar-find-in-batches-with-order/version.rb
Constant Summary collapse
- VERSION =
"0.0.2"
Instance Method Summary collapse
-
#find_each_with_order(options = {}) ⇒ Object
note that in strict mode we might itereate perpetually if the overlap in values is too high in relation to the batch size.
- #find_in_batches_with_order(options = {}) ⇒ Object
Instance Method Details
#find_each_with_order(options = {}) ⇒ Object
note that in strict mode we might itereate perpetually if the overlap in values is too high in relation to the batch size
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/ar-find-in-batches-with-order.rb', line 40 def find_each_with_order( = {}) last_record = nil find_in_batches_with_order() do |records| records.each do |record| # we need to find the last record of the previous batch next if last_record and (record != last_record) if last_record last_record = nil next end yield record end last_record = records.last end end |
#find_in_batches_with_order(options = {}) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/ar-find-in-batches-with-order.rb', line 5 def find_in_batches_with_order( = {}) relation = self # we have to be explicit about the options to ensure proper ordering and retrieval direction = .delete(:direction) || (arel.orders.first.try(:ascending?) ? :asc : nil) || (arel.orders.first.try(:descending?) ? :desc : nil) || :desc start = .delete(:start) batch_size = .delete(:batch_size) || 1000 # try to deduct the property_key, but safer to specificy directly property_key = .delete(:property_key) || arel.orders.first.try(:value).try(:name) || arel.orders.first.try(:split,' ').try(:first) sanitized_key = ActiveRecord::Base.connection.quote_column_name(property_key) relation = relation.limit(batch_size) # in strictmode, we return records with same values as the last record of the last batch strict_mode = .delete(:strict_mode) || true records = start ? (direction == :desc ? relation.where("#{sanitized_key} <= ?", start).to_a : relation.where("#{sanitized_key} >= ?", start).to_a) : relation.to_a while records.any? records_size = records.size yield records break if records_size < batch_size start = records.last.try(property_key) records = strict_mode ? (direction == :desc ? relation.where("#{sanitized_key} <= ?", start).to_a : relation.where("#{sanitized_key} >= ?", start).to_a) : (direction == :desc ? relation.where("#{sanitized_key} < ?", start).to_a : relation.where("#{sanitized_key} > ?", start).to_a) end end |