BatchDependentAssociations
Use dependent associations with Rails safely, with automatic batching.
You are viewing the README of the development version. You can find the README of the latest release (v0.2.0) here.
Branch | Status |
---|---|
Release | |
Development |
As the discussion in this open Rails issue from 2015 points out dependent: :(destroy|delete_all)
loads the entire relation and does not batch. This makes the usage of this otherwise great feature very dangerous and discouraged at the very least because of possible OOM issues.
This gem is the sweet spot between the memory safety of custom batching and the convenience of letting Rails take care of associations. When included, it prepends a before_destroy
hook that removes all has_many
associations with appropriate dependent
options. It will call destroy
or delete
if dependent
is set to :destroy
or :delete_all
respectively. nullify
and restrict_with_(error|exception)
options don't remove associations. For the documentation of dependent
options refer to Active Record Associations 4.2.2.4 (currently it incorrectly lists delete
instead of delete_all
).
Installation
Add this line to your application's Gemfile:
gem 'batch_dependent_associations'
And then execute:
$ bundle
Or install it yourself as:
$ gem install batch_dependent_associations
Usage
require "batch_dependent_associations"
class SafePerson < ActiveRecord::Base
include BatchDependentAssociations
has_many :bank_accounts, dependent: :destroy
has_many :friends, dependent: :delete_all
end
Is equivalent to:
class SafePerson < ActiveRecord::Base
has_many :bank_accounts, dependent: :destroy
has_many :friends, dependent: :delete_all
before_destroy :batch_dependent_associations, prepend: true
def batch_dependent_associations
bank_accounts.find_each(&:destroy)
friends.find_each(&:delete)
end
end
Custom batch size
Since v0.2.0
Can be set via the dependent_associations_batch_size
class variable. Default is 1000
(same as Rails default).
class SafePerson < ActiveRecord::Base
include BatchDependentAssociations
self.dependent_associations_batch_size = 500
end
Development
git clone git@github.com:thisismydesign/batch_dependent_associations.git
bundle
RAILS_ENV=test bundle exec rake db:drop db:create db:migrate
bundle exec rake
Feedback
Any feedback is much appreciated.
I can only tailor this project to fit use-cases I know about - which are usually my own ones. If you find that this might be the right direction to solve your problem too but you find that it's suboptimal or lacks features don't hesitate to contact me.
Let me know if you make use of this project so that I can prioritize further efforts.
Conventions
This gem is developed using the following conventions:
- Bundler's guide for developing a gem
- Better Specs
- Semantic versioning
- RubyGems' guide on gem naming
- RFC memo about key words used to Indicate Requirement Levels
- Bundler improvements
- Minimal dependencies
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/thisismydesign/batch_dependent_associations.