I have a model Country and therefore a table countries. The countries table act as a collection of iso country and currency codes and should never reduce there content (after I have filled it with seed data). Because Country is a subclass of ActiveRecord::Base it inherits class methods like destroy, delete_all and so forth which deletes records. I'm looking for a solution to prevent the deletion of records at the model level.
Ofc. I know that I can make use of the object oriented approach to solve this problem by overriding this methods (and raise for instance an error when they called), but this assumes that I have to know all the inherited methods of the base class. I would be glad if someone could offer a more elegant solution.
Taking inspiration from Mark Swardstrom answer, I propose the following that is working also on Rails > 5.0:
Within your model:
before_destroy :stop_destroy
def stop_destroy
errors.add(:base, :undestroyable)
throw :abort
end
The following will make all calls to model.destroy
return false
and your model will not be deleted.
You can argue that still, calls to model.delete
will work, and delete your record, but since these are lower level calls this makes perfectly sense to me.
You could also delete the records directly from the database if you want, but the above solution prevents deletion from the application level, which is the right place to check that.
Rubocop checks your calls to delete or delete_all and raises a warning, so you can be 100% sure that if you call model.delete
is because you really want it.
My solution works on latest Rails versions where you need to throw :abort
instead of returning false.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With