No release in over a year
Non-instantiated way of deleting records with dependencies quickly without instantiation.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 5.0

Runtime

>= 5.0
 Project Readme

Deprecated!

This gem is no longer maintained. It's primary function has been superceded by this gem: https://github.com/danabr75/bulk_dependency_eraser

rails_delete_all_and_assocs_without_instantiation

A recursive, class-based implementation of active_records' delete_all command, but able to also delete nested associations without record instantiation (much quicker)

Install

gem 'rails_delete_all_and_assocs_without_instantiation'

Ex usage:

# Delete all queried users and their dependecies.
# - if any errors are encountered, the transactions are rolled back
# no errors detected
User.where(email: deletable_email_list).delete_all_and_assocs_without_instantiation# => true, hash_of_classes_and_ids
# errors detected, and returned
User.where(email: deletable_email_list).delete_all_and_assocs_without_instantiation# => false, errors
# alias
User.where(email: deletable_email_list).delete_all_and_assocs_w_i
# Push past any errors to delete as many of the objects as possible
User.where(email: deletable_email_list).delete_all_and_assocs_without_instantiation!
User.where(email: deletable_email_list).delete_all_and_assocs_w_i!
User.where(email: deletable_email_list).delete_all_and_assocs_without_instantiation({force: true})

Limitations

All tables and traversed associations must have an 'id' column.

All association definitions on models with custom scopes must not have any parameters. That would require instance-evaluation. An error will be thrown if one is detected.

Ex

class User < ApplicationRecord
  # Works!
  has_many :accounts, -> { order(:created_at) }, dependent: :destroy
  # Will not work!
  has_many :creator_accounts, -> (user_id) { where(creator_id: user_id) }, dependent: :destroy, class_name: "Account"
end

Customization

class User
  # This is a way you can do more advanced filtering on association dependencies, and not just wipe everything
  # - you should try to implement the following as model association using a scope, but here's how you could handle something like that within this method.
  def self.delete_all_and_assocs_without_instantiation_builder models_and_ids_list = {}, errors = [], options = {}
    original_account_ids = models_and_ids_list['Account'] || []
    models_and_ids_list, errors = super(models_and_ids_list, errors, options)
    # we've ignored the deletion command that may or may not have been created by your assoc definition
    models_and_ids_list['Account'] = original_account_ids
    
    query = self.where({}).includes(:accounts).joins(:accounts).where(accounts: {marketable: true})
    account_ids = query.collect{|pro| pro.accounts.map(&:id) }.flatten
    models_and_ids_list, errors = Account.unscoped.where(id: account_ids).delete_all_and_assocs_without_instantiation_builder(models_and_ids_list, errors, options)

    return models_and_ids_list, errors
  end
end