Module: BatchDestroyDependentAssociations

Extended by:
ActiveSupport::Concern
Included in:
Project, User
Defined in:
app/models/concerns/batch_destroy_dependent_associations.rb

Overview

Provides a way to work around Rails issue where dependent objects are all loaded into memory before destroyed: github.com/rails/rails/issues/22510.

This concern allows an ActiveRecord module to destroy all its dependent associations in batches. The idea is borrowed from github.com/thisismydesign/batch_dependent_associations.

The differences here with that gem:

  1. We allow excluding certain associations.

  2. We don't need to support delete_all since we can use the EachBatch concern.

Constant Summary collapse

DEPENDENT_ASSOCIATIONS_BATCH_SIZE =
1000

Instance Method Summary collapse

Instance Method Details

#dependent_associations_to_destroyObject


18
19
20
# File 'app/models/concerns/batch_destroy_dependent_associations.rb', line 18

def dependent_associations_to_destroy
  self.class.reflect_on_all_associations(:has_many).select { |assoc| assoc.options[:dependent] == :destroy }
end

#destroy_dependent_associations_in_batches(exclude: []) ⇒ Object


22
23
24
25
26
27
28
29
# File 'app/models/concerns/batch_destroy_dependent_associations.rb', line 22

def destroy_dependent_associations_in_batches(exclude: [])
  dependent_associations_to_destroy.each do |association|
    next if exclude.include?(association.name)

    # rubocop:disable GitlabSecurity/PublicSend
    public_send(association.name).find_each(batch_size: DEPENDENT_ASSOCIATIONS_BATCH_SIZE, &:destroy)
  end
end