@@ -560,8 +560,9 @@ def touch_all(*names, time: nil)
560560 # Destroys the records by instantiating each
561561 # record and calling its {#destroy}[rdoc-ref:Persistence#destroy] method.
562562 # Each object's callbacks are executed (including <tt>:dependent</tt> association options).
563- # Returns the collection of objects that were destroyed; each will be frozen, to
564- # reflect that no changes should be made (since they can't be persisted).
563+ # Returns the collection of objects that were destroyed if
564+ # +config.active_record.destroy_all_in_batches+ is set to +false+. Each
565+ # will be frozen, to reflect that no changes should be made (since they can't be persisted).
565566 #
566567 # Note: Instantiation, callback execution, and deletion of each
567568 # record can be time consuming when you're removing many records at
@@ -573,8 +574,40 @@ def touch_all(*names, time: nil)
573574 # ==== Examples
574575 #
575576 # Person.where(age: 0..18).destroy_all
576- def destroy_all
577- records . each ( &:destroy ) . tap { reset }
577+ #
578+ # If +config.active_record.destroy_all_in_batches+ is set to +true+, it will ensure
579+ # to perform the record's deletion in batches
580+ # and destroy_all won't longer return the collection of the deleted records
581+ #
582+ # ==== Options
583+ # * <tt>:start</tt> - Specifies the primary key value to start from, inclusive of the value.
584+ # * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
585+ # * <tt>:batch_size</tt> - Specifies the size of the batch. Defaults to 1000.
586+ # * <tt>:error_on_ignore</tt> - Overrides the application config to specify if an error should be raised when
587+ # an order is present in the relation.
588+ # * <tt>:order</tt> - Specifies the primary key order (can be :asc or :desc). Defaults to :asc.
589+ #
590+ # NOTE: These arguments are honoured only if +config.active_record.destroy_all_in_batches+ is set to +true+.
591+ #
592+ # ==== Examples
593+ #
594+ # # Let's process from record 10_000 on, in batches of 2000.
595+ # Person.destroy_all(start: 10_000, batch_size: 2000)
596+ #
597+ def destroy_all ( start : nil , finish : nil , batch_size : 1000 , error_on_ignore : nil , order : :asc )
598+ if ActiveRecord ::Base . destroy_all_in_batches
599+ batch_options = { of : batch_size , start : start , finish : finish , error_on_ignore : error_on_ignore , order : order }
600+ in_batches ( **batch_options ) . each_record ( &:destroy ) . tap { reset }
601+ else
602+ ActiveSupport ::Deprecation . warn ( <<~MSG . squish )
603+ As of Rails 7.1, destroy_all will no longer return the collection
604+ of objects that were destroyed.
605+ To transition to the new behaviour set the following in an
606+ initializer:
607+ Rails.application.config.active_record.destroy_all_in_batches = true
608+ MSG
609+ records . each ( &:destroy ) . tap { reset }
610+ end
578611 end
579612
580613 # Deletes the records without instantiating the records
0 commit comments