require File.dirname(__FILE__) + '/acts_as_archive/gems' ActsAsArchive::Gems.activate %w(also_migrate mover) require 'also_migrate' require 'mover' $:.unshift File.dirname(__FILE__) class ActsAsArchive class < self }) options = args.last.is_a?(::Hash) ? args.pop : {} options[:copy] = true if options[:archive] options[:magic] = 'restored_at' else options[:magic] = 'deleted_at' if options[:magic].nil? options[:add] = [[ options[:magic], :datetime ]] options[:ignore] = options[:magic] options[:subtract] = 'restored_at' options[:timestamps] = false if options[:timestamps].nil? if args.empty? class_eval <<-EVAL class Archive < ActiveRecord::Base set_table_name "archived_#{self.table_name}" end EVAL args << self::Archive end args.each do |klass| klass.class_eval <<-EVAL record_timestamps = #{options[:timestamps].inspect} acts_as_archive(#{self}, :archive => true) EVAL self.reflect_on_all_associations.each do |association| if !ActsAsArchive.find(association.klass).empty? && association.options[:dependent] opts = association.options.dup opts[:class_name] = "::#{association.class_name}::Archive" opts[:foreign_key] = association.primary_key_name klass.send association.macro, association.name, opts end end unless options[:migrate] == false self.also_migrate klass.table_name, options end end end config[:to] = args config[:options] = options end def delete_all!(*args) ActsAsArchive.disable { self.delete_all(*args) } end def destroy_all!(*args) ActsAsArchive.disable { self.destroy_all(*args) } end def migrate_from_acts_as_paranoid time = Benchmark.measure do ActsAsArchive.find(self).each do |config| config = config.dup config[:options][:copy] = false ActsAsArchive.move( config, "`#{config[:options][:magic]}` IS NOT NULL", :migrate => true ) end end $stdout.puts "-- #{self}.migrate_from_acts_as_paranoid" $stdout.puts " -> #{"%.4fs" % time.real}" end def restore_all(*args) ActsAsArchive.deprecate "#{self}.restore_all is deprecated, please use #{self}.delete_all." self.delete_all *args end end module InstanceMethods def delete!(*args) ActsAsArchive.disable { self.delete(*args) } end def destroy!(*args) ActsAsArchive.disable { self.destroy(*args) } end end end module DatabaseStatements def self.included(base) unless base.included_modules.include?(InstanceMethods) base.send :include, InstanceMethods base.class_eval do unless method_defined?(:delete_sql_without_archive) alias_method :delete_sql_without_archive, :delete_sql alias_method :delete_sql, :delete_sql_with_archive end end end end module InstanceMethods def delete_sql_with_archive(sql, name = nil) unless ActsAsArchive.disabled from, where = /DELETE FROM (.+)/i.match(sql)[1].split(/\s+WHERE\s+/i, 2) from = from.strip.gsub(/`/, '').split(/\s*,\s*/) ActsAsArchive.find(from).each do |config| ActsAsArchive.move(config, where) end end delete_sql_without_archive(sql, name) end end end end ::ActiveRecord::Base.send(:include, ::ActsAsArchive::Base) ::ActiveRecord::ConnectionAdapters::DatabaseStatements.send(:include, ::ActsAsArchive::DatabaseStatements)