@@ -338,23 +338,17 @@ def get_the_order_of_primary_key(order)
338
338
339
339
def batch_on_loaded_relation ( relation :, start :, finish :, order :, batch_limit :)
340
340
records = relation . to_a
341
+ order = build_batch_orders ( order ) . map ( &:second )
341
342
342
343
if start || finish
343
344
records = records . filter do |record |
344
- id = record . id
345
-
346
- if order == :asc
347
- ( start . nil? || id >= start ) && ( finish . nil? || id <= finish )
348
- else
349
- ( start . nil? || id <= start ) && ( finish . nil? || id >= finish )
350
- end
345
+ ( start . nil? || compare_values_for_order ( record . id , start , order ) >= 0 ) &&
346
+ ( finish . nil? || compare_values_for_order ( record . id , finish , order ) <= 0 )
351
347
end
352
348
end
353
349
354
- records . sort_by! ( &:id )
355
-
356
- if order == :desc
357
- records . reverse!
350
+ records . sort! do |record1 , record2 |
351
+ compare_values_for_order ( record1 . id , record2 . id , order )
358
352
end
359
353
360
354
records . each_slice ( batch_limit ) do |subrecords |
@@ -367,6 +361,28 @@ def batch_on_loaded_relation(relation:, start:, finish:, order:, batch_limit:)
367
361
nil
368
362
end
369
363
364
+ # This is a custom implementation of `<=>` operator,
365
+ # which also takes into account how the collection will be ordered.
366
+ def compare_values_for_order ( value1 , value2 , order )
367
+ # Multiple column values.
368
+ if value1 . is_a? ( Array )
369
+ value1 . each_with_index do |element1 , index |
370
+ element2 = value2 [ index ]
371
+ direction = order [ index ]
372
+ comparison = element1 <=> element2
373
+ comparison = -comparison if direction == :desc
374
+ return comparison if comparison != 0
375
+ end
376
+
377
+ 0
378
+ # Single column values.
379
+ elsif order . first == :asc
380
+ value1 <=> value2
381
+ else
382
+ value2 <=> value1
383
+ end
384
+ end
385
+
370
386
def batch_on_unloaded_relation ( relation :, start :, finish :, load :, order :, use_ranges :, remaining :, batch_limit :)
371
387
batch_orders = build_batch_orders ( order )
372
388
relation = relation . reorder ( batch_orders . to_h ) . limit ( batch_limit )
0 commit comments