This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
commit 0ff304f767832f8dd63d23e1e907b104e4b9efee
tree 18039f17bc54f09da4fd9de83b82e5877d21437e
parent e0f394637eb60cda51a67e6ed3bee0134a8cb212
tree 18039f17bc54f09da4fd9de83b82e5877d21437e
parent e0f394637eb60cda51a67e6ed3bee0134a8cb212
| name | age | message | |
|---|---|---|---|
| |
.gitignore | Mon May 19 12:51:45 -0700 2008 | [ajh] |
| |
COPYING | Thu May 15 14:42:07 -0700 2008 | [ajh] |
| |
README | Mon May 19 11:15:25 -0700 2008 | [ajh] |
| |
Rakefile | Thu Mar 13 12:32:00 -0700 2008 | [(no author)] |
| |
init.rb | Thu Mar 13 14:52:16 -0700 2008 | [(no author)] |
| |
lib/ | Mon May 19 11:15:25 -0700 2008 | [ajh] |
| |
test/ | Thu Mar 13 14:52:16 -0700 2008 | [(no author)] |
README
Copyright (C) 2008 Substantial and Andy Hartford <hartforda @ gmail.com>
=== acts_as_soft_deletable ===
This plugin provides the ability to soft delete ActiveRecord models. When
models are destroyed, they will be archived into a special deleted table.
They can later be restored easily.
<pre>
class Artist < ActiveRecord::Base
acts_as_soft_deletable # This will wrap the destroy method to provide soft delete
# support and create a new ActiveRecord class called Artist::Deleted
end
model = Artist.find(34)
model.destroy # removes row from artists table, and adds a row to
# deleted_artists table
deleted = Artist::Deleted.find(34)
deleted.undestroy! # adds the row back to the artists table, and removes
# if from the deleted_artists table
restored = Artist.find(34) # The artist is restored with all the same
# information. The updated_at column will be
# Time.now if it exists.
</pre>
=== Compare to acts_as_paranoid ===
Acts_as_paranoid takes the approach of using a deleted_at flag in the models table. If the deleted_at column has a
value, the row is considered 'deleted'. The problem with this approach is that all finds on the model have to exclude
'deleted' rows. This turns out be be a challenge. Acts_as_paranoid patches the ActiveRecord internals to accomplish
this, but it is fragile and could break with future changes to ActiveRecord. Also, some of the more exotic finds
currently don't work (has_many :through with polymorphism as of March 2008) and supporting them means running on an
upgrade treadmill to keep up with the evolution of ActiveRecord.
This plugin avoids these problems by allowing the row to be deleted and archiving it into another table. The behavior of
ActiveRecord::Base#Find doesn't have to change which should mean that this plugin is more immune to breaking due to
ActiveRecord development. Queries on the live table will also be faster in the case of lots of deleted rows, because
they will be in a seperate table. The tradeoff is that the deleted table needs to be maintained along with the live
table. For example, if the artists table adds a column in a future migration, then the deleted_artists table needs that
column as well.
A migration helper is available (see below) that will help keep the deleted table in sync. Also, a unit test helper is
provided (again, see below) which adds unit tests to the model ensuring soft delete is working. If this is used, the
test will fail if the deleted table gets out of sync.
=== Setup ===
---+ Model
Any ActiveRecord class that wants the soft delete functionality should add
the following line to their class definition:
<pre>
class SomeModel < ActiveRecord::Base
acts_as_soft_deletable
...
</pre>
---+ Migration
and setup the deleted table with the following migration:
<pre>
class AddActsAsSoftDeletable < ActiveRecord::Migration
def self.up
SomeModel::Deleted.create_table
end
def self.down
SomeModel::Deleted.drop_table
end
end
</pre>
Any changes to the original table (such as adding a column) should be reflected in the deleted table. Use the
update_columns method:
<pre>
class AddSkuColumn < ActiveRecord::Migration
def self.up
add_column 'items', 'sku', :string
Item::Deleted.update_columns # will add sku column
end
def self.down
remove_column 'items', 'sku'
Item::Deleted.update_columns # will remove sku column
end
end
</pre>
Note that update_columns will happily delete columns if asked which will lose data forever. I'm not sure if this
behavior is fine or horrifying, but it's definitely something to keep in mind. I'd appreciate feedback on this.
---+ Unit tests
A model's soft delete capabilities can be easily unit tested by using this provided assert:
<pre>
def test_soft_delete_works
# will run the model through a destroy and undestroy while making sure all values were saved
assert_model_soft_deletes( items(:radar_detector) )
end
</pre>
This was developed with Test::Unit in mind. Not sure how well it works with rspec.
=== Thanks ===
Substantial, my employer for letting me release this
acts_as_paranoid and technoweenie, for a plugin I've got good years of use out of
acts_as_versioned, who's approach influenced this plugin
Danimal, for the feedback on rubyonrails-talk





