diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index ebfbfae0b9..64b35434ed 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -341,7 +341,13 @@ def batch_on_loaded_relation(relation:, start:, finish:, order:, batch_limit:) if start || finish records = records.filter do |record| - (start.nil? || record.id >= start) && (finish.nil? || record.id <= finish) + id = record.id + + if order == :asc + (start.nil? || id >= start) && (finish.nil? || id <= finish) + else + (start.nil? || id <= start) && (finish.nil? || id >= finish) + end end end diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index a814eaab14..c3618a2ee3 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -506,6 +506,23 @@ def test_in_batches_when_loaded_runs_no_queries_with_start_and_end_arguments assert_equal posts.size - 2, batch_count end + def test_in_batches_when_loaded_runs_no_queries_with_start_and_end_arguments_and_reverse_order + posts = Post.all.order(id: :asc) + posts.load + batch_count = 0 + + start_id = posts.map(&:id)[-2] + finish_id = posts.map(&:id)[1] + assert_queries_count(0) do + posts.in_batches(of: 1, start: start_id, finish: finish_id, order: :desc) do |relation| + batch_count += 1 + assert_kind_of ActiveRecord::Relation, relation + end + end + + assert_equal posts.size - 2, batch_count + end + def test_in_batches_when_loaded_can_return_an_enum posts = Post.all posts.load