aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorSantiago Pastorino <santiago@wyeworks.com>2011-07-14 07:57:04 -0700
committerSantiago Pastorino <santiago@wyeworks.com>2011-07-14 07:57:04 -0700
commitd632e927ec06f4aa0dfd6bba2d554ca9f460de55 (patch)
tree369e8bb28870dfd457c085ae3e450718406c7420 /activerecord
parentdb0a65cbe0a819e0fe325250155b3e2f0f01e6e2 (diff)
parent96be08de257460cfd66d7f946be95e07160cea6f (diff)
downloadrails-d632e927ec06f4aa0dfd6bba2d554ca9f460de55.tar.gz
rails-d632e927ec06f4aa0dfd6bba2d554ca9f460de55.tar.bz2
rails-d632e927ec06f4aa0dfd6bba2d554ca9f460de55.zip
Merge pull request #1807 from caius/find_in_batches_id_bug
Bugfix by stopping find_in_batches using the records after yielding.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/relation/batches.rb7
-rw-r--r--activerecord/test/cases/batches_test.rb16
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