<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>.gitignore</filename>
    </added>
    <added>
      <filename>rails/init.rb</filename>
    </added>
    <added>
      <filename>test/database.yml</filename>
    </added>
    <added>
      <filename>test/schema.rb</filename>
    </added>
    <added>
      <filename>test/test_helper.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,10 +1,14 @@
 ActsAsDeleted
 =============
 
-Rails plugin to hide records instead of delete.
+This plugin is based on the original plugin by kivanio.
+
+Rails plugin to enable soft delete of records. Some fixes for callbacks (before_delete,
+after_delete, before_undelete, after_undelete) were added. Additionally most of the parts
+have got tests.
 
 Install plugin:
-script/plugin install git://github.com/kivanio/acts_as_deleted.git
+script/plugin install git://github.com/chlu/acts_as_deleted.git
 
 Example
 =======
@@ -17,7 +21,7 @@ class CreateCars &lt; ActiveRecord::Migration
       t.string :name
 
       # Use &quot;deletestamps&quot; to create columns &quot;deleted&quot; and &quot;deleted_at&quot;
-      # With argument &quot;true&quot;, will be create a column &quot;deleted_id&quot; to use with restful-authentication plugin
+      # With &quot;true&quot;, a column &quot;deleted_by&quot; will be created to set an user id (e.g. with restful-authentication)
       t.deletestamps(true)
       
       t.timestamps
@@ -29,17 +33,19 @@ class CreateCars &lt; ActiveRecord::Migration
   end
 end
 
-
-
 In your model:
 
 class Car &lt; ActiveRecord::Base
-  # default names scopes: &quot;with_deleted&quot; and &quot;without_deleted&quot;
+  # Use default named scopes: &quot;only_deleted&quot; and &quot;without_deleted&quot;
   acts_as_deleted
-  
-  # You can set names of scopes
-  acts_as_deleted(:deleteed,:no_deleteed)
 
+  # You can use callbacks for delete and undelete just like other active record callbacks
+  after_delete :notify_someone
+
+protected
+  def notify_someone
+    logger.info('Your car has been deleted. Ouch.')
+  end
 end
 
 After that in your Controller:
@@ -47,30 +53,10 @@ After that in your Controller:
 class CarController &lt; ApplicationController
   
   # Use scope &quot;without_deleted&quot; to find normal records
-  def normal_records
-    @cars = Car.without_deleted.find :all
-  end
-  
-  # Use scope &quot;with_deleted&quot; to find deleted records
-  def deleted_records
-    @cars = Car.with_deleted.find :all
-  end
-  
-  # Use custom scope &quot;deleteed&quot; to find normal records
-  def normal_records
-    @cars = Car.deleteed.find :all
+  def index
+    @cars = Car.without_deleted
   end
   
-  # Use custom scope &quot;no_deleteed&quot; to find deleted records
-  def deleted_records
-    @cars = Car.no_deleteed.find :all
-  end
-  
-  #Use just normal find of rails to get all records
-  def all
-    @cars = car.find :all
-  end
-
   # In destroy action use &quot;delete&quot; method to hide a record
   def destroy
    @car = Car.find(params[:id])
@@ -82,13 +68,18 @@ class CarController &lt; ApplicationController
   
   # When you use plugin restful-authentication, you can use &quot;delete_with_user&quot; to save user
   def destroy_with_user
-     @car = Car.find(params[:id])
-      if @car.delete_with_user(current_user.id)
-        flash[:notice] = 'Bye Bye Car.'
-      end
-      redirect_to(cars_url)
+    @car = Car.find(params[:id])
+    if @car.delete_with_user(current_user.id)
+      flash[:notice] = 'Bye Bye Car.'
     end
-
+    redirect_to(cars_url)
+  end
+  
+  # A record can be undeleted
+  def undelete
+    @car = Car.find(params[:id])
+    @car.undelete
+  end
 end
 
 </diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -8,10 +8,11 @@ module Acts #:nodoc:
 
     module ClassMethods
       # You can pass name of scope that you want to use
-      def acts_as_deleted(deleted=:with_deleted,not_deleted=:without_deleted)
-        self.before_validation_on_create  :undelete
-        named_scope deleted, :conditions =&gt; {:deleted =&gt; true}
-        named_scope not_deleted, :conditions =&gt; {:deleted =&gt; false}
+      def acts_as_deleted(deleted = :only_deleted, not_deleted = :without_deleted)
+        named_scope deleted, :conditions =&gt; { :deleted =&gt; true }
+        named_scope not_deleted, :conditions =&gt; { :deleted =&gt; false }
+        
+        define_callbacks :before_delete, :after_delete, :before_undelete, :after_undelete
         
         include InstanceMethods unless self.included_modules.include?(InstanceMethods)
       end
@@ -20,27 +21,36 @@ module Acts #:nodoc:
     module InstanceMethods
       # Set record as undeleted
       def undelete
-        write_attribute('deleted', 0) if respond_to?(:deleted)
+        callback(:before_undelete)
+        write_attribute('deleted', false) if respond_to?(:deleted)
+        write_attribute('deleted_at', nil) if respond_to?(:deleted_at)
+        self.save(false)
+        callback(:after_undelete)
       end
-      # set record as deleted
-
+      
+      # Set record as deleted
       def delete
-        t = self.class.default_timezone == :utc ? Time.now.utc : Time.now
-        write_attribute('deleted', 1) if respond_to?(:deleted)
-        write_attribute('deleted_at', t) if respond_to?(:deleted_at)
-        self.save(false)
+        callback(:before_delete)
+        delete_without_callbacks
+        callback(:after_delete)
       end
 
-      # set record as deleted with user.
+      # Set record as deleted with user.
       # Compatible with restful-authentication
       def delete_with_user(user_id)
+        callback(:before_delete)
+        write_attribute('deleted_by', user_id) if respond_to?(:deleted_by)
+        delete_without_callbacks
+        callback(:after_delete)
+      end
+
+    protected
+      def delete_without_callbacks
         t = self.class.default_timezone == :utc ? Time.now.utc : Time.now
+        write_attribute('deleted', true) if respond_to?(:deleted)
         write_attribute('deleted_at', t) if respond_to?(:deleted_at)
-        write_attribute('deleted', 1) if respond_to?(:deleted)
-        write_attribute('deleted_id', user_id) if respond_to?(:deleted_id)
         self.save(false)
       end
-
     end
   end
 end</diff>
      <filename>lib/acts_as_deleted.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,10 +5,10 @@ module Acts
     end
 
     module InstanceMethods
-      def deletestamps(include_deleted_id = false)
-        column(:deleted, :boolean)
+      def deletestamps(include_deleted_by = false)
+        column(:deleted, :boolean, :default =&gt; false)
         column(:deleted_at, :datetime)
-        column(:deleted_id, :integer) if include_deleted_id
+        column(:deleted_by, :integer) if include_deleted_by
       end
     end
   end</diff>
      <filename>lib/acts_as_deleted_migration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,104 @@
-require 'test/unit'
+require File.dirname(__FILE__) + '/test_helper.rb'
 
 class ActsAsDeletedTest &lt; Test::Unit::TestCase
-  # Replace this with your real tests.
-  def test_this_plugin
-    flunk
+  load_schema
+  
+  # FIXME this is bloated and should be mocked for better testing style of callbacks
+  class Thingy &lt; ActiveRecord::Base
+    acts_as_deleted
+    
+    before_delete :before_deleted
+    after_delete :after_deleted
+    
+    before_undelete :before_undeleted
+    after_undelete :after_undeleted
+    
+    attr_reader :deleted_before, :deleted_after, :undeleted_before, :undeleted_after
+    
+  protected
+    def before_deleted
+      @deleted_before = deleted
+    end
+    
+    def after_deleted
+      @deleted_after = deleted
+    end
+    
+    def before_undeleted
+      @undeleted_before = deleted
+    end
+    
+    def after_undeleted
+      @undeleted_after = deleted
+    end
+  end
+  
+  # TODO better use transactional testing
+  def teardown
+    Thingy.delete_all
+  end
+
+  def test_schema_has_loaded_correctly
+    assert_equal [], Thingy.all
+  end  
+  
+  def test_named_scope_deleted
+    deleted_scope = { :conditions =&gt; { :deleted =&gt; true } }
+    assert_equal deleted_scope, Thingy.only_deleted.proxy_options
+  end
+
+  def test_named_scope_not_deleted
+    not_deleted_scope = { :conditions =&gt; { :deleted =&gt; false } }
+    assert_equal not_deleted_scope, Thingy.without_deleted.proxy_options
+  end
+
+  def test_delete_sets_deleted_and_saves_record
+    thingy = Thingy.create(:name =&gt; 'Foo')
+    assert_equal false, thingy.deleted
+    thingy.delete
+    thingy.reload
+    assert_equal true, thingy.deleted
+  end
+  
+  def test_delete_sets_timestamp
+  	time = Time.now
+    thingy = Thingy.create(:name =&gt; 'Foo')
+    thingy.delete
+    assert thingy.deleted_at &gt; time
+  end
+  
+  def test_delete_calls_before_delete_callback
+    thingy = Thingy.create(:name =&gt; 'Foo')
+    thingy.delete
+    assert_equal false, thingy.deleted_before
+  end
+  
+  def test_delete_calls_after_delete_callback
+    thingy = Thingy.create(:name =&gt; 'Foo')
+    thingy.delete
+    assert_equal true, thingy.deleted_after
+  end
+  
+  def test_undelete_unsets_deleted_and_deleted_at_and_saves_record
+    thingy = Thingy.create(:name =&gt; 'Foo')
+    thingy.delete
+    thingy.undelete
+    thingy.reload
+    assert_equal false, thingy.deleted
+    assert_nil thingy.deleted_at
+  end
+  
+  def test_undelete_calls_before_undelete_callback
+    thingy = Thingy.create(:name =&gt; 'Foo')
+    thingy.delete
+    thingy.undelete
+    assert_equal true, thingy.deleted_after
+  end
+  
+  def test_delete_with_user_sets_deleted_by_to_user_id
+    thingy = Thingy.create(:name =&gt; 'Foo')
+    thingy.delete_with_user(42)
+    thingy.reload
+    assert_equal 42, thingy.deleted_by
   end
 end</diff>
      <filename>test/acts_as_deleted_test.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>init.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>8b16709c6b82f77e58d49cc8bd449a6f04840bf0</id>
    </parent>
  </parents>
  <author>
    <name>Christopher Hlubek</name>
    <email>hlubek@networkteam.com</email>
  </author>
  <url>http://github.com/kivanio/acts_as_deleted/commit/fe20926141f51f252373be07853aa00a88410334</url>
  <id>fe20926141f51f252373be07853aa00a88410334</id>
  <committed-date>2009-02-17T09:03:35-08:00</committed-date>
  <authored-date>2009-02-17T09:03:35-08:00</authored-date>
  <message>Callbacks for delete and undelete, code cleanups, unit tests for most of the features</message>
  <tree>d75af97ff473a08b5645e25394e3db74ebc0c603</tree>
  <committer>
    <name>Christopher Hlubek</name>
    <email>hlubek@networkteam.com</email>
  </committer>
</commit>
