1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Return sized enumerator from Batches#find_in_batches

This commit is contained in:
Marc-Andre Lafortune 2014-01-29 14:53:54 -05:00
parent 4499ab5fde
commit d37f395be8
3 changed files with 25 additions and 4 deletions

View file

@ -1,3 +1,9 @@
* `find_in_batches` now returns an `Enumerator` that can calculate its size.
See also #13938.
*Marc-André Lafortune*
* Make sure transaction state gets reset after a commit operation on the record. * Make sure transaction state gets reset after a commit operation on the record.
If a new transaction was open inside a callback, the record was loosing track If a new transaction was open inside a callback, the record was loosing track

View file

@ -96,17 +96,22 @@ module ActiveRecord
# the batch sizes. # the batch sizes.
def find_in_batches(options = {}) def find_in_batches(options = {})
options.assert_valid_keys(:start, :batch_size) options.assert_valid_keys(:start, :batch_size)
return to_enum(:find_in_batches, options) unless block_given?
relation = self relation = self
start = options[:start]
batch_size = options[:batch_size] || 1000
unless block_given?
return to_enum(:find_in_batches, options) do
total = start ? where(table[primary_key].gteq(start)).size : size
(total - 1).div(batch_size) + 1
end
end
if logger && (arel.orders.present? || arel.taken.present?) if logger && (arel.orders.present? || arel.taken.present?)
logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size") logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size")
end end
start = options[:start]
batch_size = options[:batch_size] || 1000
relation = relation.reorder(batch_order).limit(batch_size) relation = relation.reorder(batch_order).limit(batch_size)
records = start ? relation.where(table[primary_key].gteq(start)).to_a : relation.to_a records = start ? relation.where(table[primary_key].gteq(start)).to_a : relation.to_a

View file

@ -191,4 +191,14 @@ class EachTest < ActiveRecord::TestCase
end end
end end
end end
if Enumerator.method_defined? :size
def test_find_in_batches_should_return_a_sized_enumerator
assert_equal 11, Post.find_in_batches(:batch_size => 1).size
assert_equal 6, Post.find_in_batches(:batch_size => 2).size
assert_equal 4, Post.find_in_batches(:batch_size => 2, :start => 4).size
assert_equal 4, Post.find_in_batches(:batch_size => 3).size
assert_equal 1, Post.find_in_batches(:batch_size => 10_000).size
end
end
end end