@@ -10,7 +10,15 @@ module Mongoid
 
       included do
         class_attribute :dependents
+        class_attribute :dependents_owner
         self.dependents = []
+        self.dependents_owner = self
+      end
+
+      class_methods do
+        def _all_dependents
+          dependents + (superclass.respond_to?(:_all_dependents) ? superclass._all_dependents : [])
+        end
       end
 
       # The valid dependent strategies.
# frozen_string_literal: true

module Mongoid
  module Association

    # This module defines the behaviour for setting up cascading deletes and
    # nullifies for relations, and how to delegate to the appropriate strategy.
    module Depending
      extend ActiveSupport::Concern

      included do
        class_attribute :dependents
        self.dependents = []
      end

      # The valid dependent strategies.
      #
      # @since 7.0
      STRATEGIES = [
          :delete_all,
          :destroy,
          :nullify,
          :restrict_with_exception,
          :restrict_with_error
      ]

      # The error message when a strategy cannot delete objects because there are associated objects.
      #
      # @since 7.0
      RESTRICT_ERROR_MSG = 'Cannot delete record because associated objects exist.'.freeze

      # Attempt to add the cascading information for the document to know how
      # to handle associated documents on a removal.
      #
      # @example Set up cascading information
      #   Mongoid::Association::Depending.define_dependency!(association)
      #
      # @param [ Association ] association The association metadata.
      #
      # @return [ Class ] The class of the document.
      #
      # @since 2.0.0.rc.1
      def self.define_dependency!(association)
        validate!(association)
        association.inverse_class.tap do |klass|
          if association.dependent && !klass.dependents.include?(association)
            klass.dependents.push(association)
          end
        end
      end

      def self.validate!(association)
        unless STRATEGIES.include?(association.dependent)
          raise Errors::InvalidDependentStrategy.new(association,
                                                     association.dependent,
                                                     STRATEGIES)
        end
      end

      # Perform all cascading deletes, destroys, or nullifies. Will delegate to
      # the appropriate strategy to perform the operation.
      #
      # @example Execute cascades.
      #   document.apply_delete_dependencies!
      #
      # @since 2.0.0.rc.1
      def apply_delete_dependencies!
        dependents.each do |association|
          if association.try(:dependent)
            send("_dependent_#{association.dependent}!", association)
          end
        end
      end

      private

      def _dependent_delete_all!(association)
        if relation = send(association.name)
          if relation.respond_to?(:dependents) && relation.dependents.blank?
            relation.clear
          else
            ::Array.wrap(send(association.name)).each { |rel| rel.delete }
          end
        end
      end

      def _dependent_destroy!(association)
        if relation = send(association.name)
          if relation.is_a?(Enumerable)
            relation.entries
            relation.each { |doc| doc.destroy }
          else
            relation.destroy
          end
        end
      end

      def _dependent_nullify!(association)
        if relation = send(association.name)
          relation.nullify
        end
      end

      def _dependent_restrict_with_exception!(association)
        if (relation = send(association.name)) && !relation.blank?
          raise Errors::DeleteRestriction.new(relation, association.name)
        end
      end

      def _dependent_restrict_with_error!(association)
        if (relation = send(association.name)) && !relation.blank?
          errors.add(association.name, RESTRICT_ERROR_MSG)
          throw(:abort, false)
        end
      end
    end
  end
end

Can this be marked `@api private` please.