Today I had an interesting feature request to implement: Get rid of all deletions and replace them with a
deleted flag in the DB.
It's the usual story: Nobody really does deletes but rather everything is put into the DB in case it's needed at some later point. Unfortunately I didn't know about this particular feature until after I had finished most of the coding for the Rails application so going through the code and removing all destroy code from controllers was pretty much out of the question.
Instead I remembered reading about Modules in Ruby and how they can bolt on functionality to Classes.
Turns out it's totally trivial to remove deletion from Rails Models with 10 odd lines of code in a completely transparent an unobtrusive way:
unless self.respond_to? :deleted
self.update_attribute :deleted, true
default_scope where( :deleted => false )
class MissingMigrationException < Exception
"Model is lacking the deleted boolean field for NotDeleteable to work"
This will override the default destroy/delete method provided by
and also install a default_scope into the Model class so Rails will by default append
WHERE deleted = false
to all SQL queries made through the ActiveRecord Query Interface
You use this by simply including this module inside your Model class:
class User < ActiveRecord::Base
Did I mention that I really like Ruby?
Word of warning:
I have no clue if I am breaking
:dependant => :destroy on ActiveRecord relations in any way, but I suspect it should still be alright.
Update: The original code had an issue where you could not mark a record that is invalid as deleted. This was due to the fact that I was using
save instead of