diff options
-rw-r--r-- | activerecord/lib/active_record/relation/batches.rb | 7 | ||||
-rw-r--r-- | activerecord/test/cases/batches_test.rb | 16 |
2 files changed, 21 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index 46ab67d1cf..ec1176e3dd 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -66,11 +66,14 @@ module ActiveRecord records = relation.where(table[primary_key].gteq(start)).all while records.any? + records_size = records.size + primary_key_offset = records.last.id + yield records - break if records.size < batch_size + break if records_size < batch_size - if primary_key_offset = records.last.id + if primary_key_offset records = relation.where(table[primary_key].gt(primary_key_offset)).to_a else raise "Primary key not included in the custom select clause" diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index 50ddf6c757..a35baee4ed 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -100,4 +100,20 @@ class EachTest < ActiveRecord::TestCase end end end + + def test_find_in_batches_should_not_use_records_after_yielding_them_in_case_original_array_is_modified + not_a_post = "not a post" + not_a_post.stubs(:id).raises(StandardError, "not_a_post had #id called on it") + + assert_nothing_raised do + Post.find_in_batches(:batch_size => 1) do |batch| + assert_kind_of Array, batch + assert_kind_of Post, batch.first + + batch.map! { not_a_post } + end + end + + end + end |