Build status for all matrix combinations listed in compatibility
class Harbor has_many :ships accepts_nested_attributes_for :ships, allow_destroy: true end harbor.ships_attributes = [harbor.ships.first.attributes.merge('_destroy': true)] harbor.save! harbor.ships_destroyed_during_save? # true
See that last line of code? That is what this gem adds :smiley:
Active Record offers introspection of saved changes for almost everything you could want. The one thing I have repeatedly found myself wishing for was a way to know if a nested attribute was destroyed during save via accepts_nested_attributes.
The only way I know to find that information is to set a flag in a callback before saving, then use that flag for state comparison after the save completes.
This gem handles setting the flags before saving and adds introspection into the state after the save.
Add this line to your application's Gemfile:
And then execute:
$ bundle install
Or install it yourself as:
$ gem install activerecord-nested_attribute_destruction
When you call
#accepts_nested_attributes_for, this gem will automatically
install its hooks on the class. One method is also added to the class instance
has_many :ships has_one :accountant accepts_nested_attributes_for :ships, :accountant, allow_destroy: true
You can call
accountant_destroyed_during_save? after a save to check if associated ships or
the accountant were destroyed through nested attribute assignment during the
Here is an example of how it works, adapted from the test suite.
def print_result(h) if h.ships_destroyed_during_save? puts "At least one ship was destroyed during the last save operation" else puts "No ships were destroyed during the last save operation" end end harbor = DangerousHarbor.create(name: 'Blue Lagoon') ship1 = (harbor.ships << Ship.create(harbor: harbor)).first ship2 = (harbor.ships << Ship.create(harbor: harbor)).first harbor.ships_attributes = [ ship1.attributes.merge('_destroy': true), ship2.attributes.merge(fuel_remaining: 10) ] harbor.save! print_result(harbor) harbor.save! print_result(harbor)
and the output when the code above is run:
At least one ship was destroyed during the last save operation No ships were destroyed during the last save operation
To see more examples, take a look at the tests.
This gem should be compatible with all versions of Ruby 2.3 and higher. It should be compatible with Active Record versions 5.2 and up.
Because of rubocop dependencies and keyword arguments changes in Ruby 3.0 which affected the database setup code used in the test suite, it is only tested against the matrices displayed below.
Sorted by Active Record version
|Active Record version||Ruby Version|
Sorted by Ruby version
|Ruby Version||Active Record version|
The safe navigation operator, introduced in Ruby 2.3, is used.
The API changes in Active Record 5.2 are necessary for the core functionality of the gem.
After checking out the repo, run
bin/setup to install dependencies. Then, run
rake spec to run the tests. You can also run
bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run
bundle exec rake install. To release a new version, update the version number in
version.rb, and then run
bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the
.gem file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/brandoncc/activerecord-nested\_attribute\_destruction. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.