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.
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.
def find_in_batches(options = {})
options.assert_valid_keys(:start, :batch_size)
return to_enum(:find_in_batches, options) unless block_given?
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?)
logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size")
end
start = options[:start]
batch_size = options[:batch_size] || 1000
relation = relation.reorder(batch_order).limit(batch_size)
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
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