module HipstersInc module Acts module Restorable def self.included(mod) mod.extend(ClassMethods) end module ClassMethods def acts_as_restorable(opts = {}) write_inheritable_attribute(:backup_table, opts[:backup_table] || DeletedRecord) write_inheritable_attribute(:acts_as_undeletable, true) class_eval do extend HipstersInc::Acts::Restorable::SingletonMethods end include HipstersInc::Acts::Restorable::InstanceMethods alias_method :before_destory_without_backup, :before_destroy unless method_defined?(:before_destory_without_backup) alias_method :before_destroy, :before_destory_with_backup end def restore_from_xml(xml, params = {}) doc = REXML::Document.new(xml) root = doc.elements[1] root.elements.each do |el| params[el.name.to_sym] = el.text end new(params) end end module SingletonMethods end module InstanceMethods def as_xml(opts = {}) to_xml(opts) end def before_destory_with_backup dependents = [] self.class.reflect_on_all_associations.each do |association| dependents << association.name if association.options[:dependent] == :destroy end self.class.read_inheritable_attribute(:backup_table).create( :model => self.class.to_s, :model_primary_key => self.id, :record_data => self.to_xml(:include => dependents) ) before_destory_without_backup end end end end end ActiveRecord::Base.class_eval do include HipstersInc::Acts::Restorable end