Skip to content

Instantly share code, notes, and snippets.

@eef
Created November 29, 2013 12:18
Show Gist options
  • Save eef/7704897 to your computer and use it in GitHub Desktop.
Save eef/7704897 to your computer and use it in GitHub Desktop.
module SoftDelete
def destroy
unless self.respond_to? :deleted_at
raise MissingMigrationException
end
self.update_attribute :deleted_at, Time.now
run_callbacks :destroy if self.is_a?(Performer)
freeze
end
def restore
unless self.deleted_at.nil?
self.update_attribute :deleted_at, nil
end
restore_associations
end
def delete
self.destroy
end
private
def restore_associations
self.class.reflect_on_all_associations.each do |reflection|
macro = reflection.macro
restorer_class = "Restore#{macro.to_s.camelize}".constantize
restorer = restorer_class.new(self, reflection.name)
restorer.restore if reflection.name.to_s.eql?("user")
end
end
end
class Restore
def initialize(parent_model, model_name)
@parent_model = parent_model
@model_name = model_name.to_s
end
def restore
objects = load_objects
objects.each do |object|
object.restore unless (object.nil? or !object.class.ancestors.include?(SoftDelete))
end
end
protected
def load_objects
@parent_model.send(@model_name)
end
end
class RestoreHasOne < Restore
def initialize(parent_model, model_name)
@parent_model = parent_model
@model_name = model_name.to_s.singularize
end
def restore
object = load_objects
object.restore unless (object.nil? or !object.class.ancestors.include?(SoftDelete))
end
end
class RestoreHasMany < Restore; end
class RestoreHasAndBelongsToMany < Restore; end
class RestoreBelongsTo < RestoreHasOne; end
class MissingMigrationException < Exception
def message
"Model requires a deleted_at timestamp field"
end
end
class NotDeletedException < Exception
def message
"Object has not been deleted"
end
end
class NotSoftDeleteableException < Exception
def message
"Model is not soft deleteable"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment