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 (
(no author) (author)
Thu Mar 13 15:57:11 -0700 2008
commit 42b5ed405b984f691364c56a0c8b6331bfdf02e9
tree d0d4ede310d0772090585f243ed2c34df3089f55
parent a3a974e428d5afbe2e625d10ad13b46a6c3316ec
tree d0d4ede310d0772090585f243ed2c34df3089f55
parent a3a974e428d5afbe2e625d10ad13b46a6c3316ec
| name | age | message | |
|---|---|---|---|
| |
README | Thu Mar 13 14:52:16 -0700 2008 | [(no author)] |
| |
Rakefile | Thu Mar 13 12:32:00 -0700 2008 | [(no author)] |
| |
init.rb | Thu Mar 13 14:52:16 -0700 2008 | [(no author)] |
| |
lib/ | Thu Mar 13 15:57:11 -0700 2008 | [(no author)] |
| |
test/ | Thu Mar 13 14:52:16 -0700 2008 | [(no author)] |
README
=== 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
# This will wrap the destroy method to provide soft delete
# support and create a new ActiveRecord class called Artist::Deleted
acts_as_soft_deletable
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. This has the drawback that finds on
the model have to exclude deleted rows. This behaviour change turns out be be a challenge. Acts_as_paranoid tries to
patch the ActiveRecord internals to accomplish this, but ActiveRecord could change in the future causing acts_as_parnoid
to break. Also, there are some exotic finds that need to be considered like "has_many through with polymorphism". This
doesn't exclude deleted models as it should in acts_as_paranoid (March 2008).
This plugin avoids the problem of changing find's behavior by allowing the row to really be
deleted and archiving it into another table. The advantages are that its hook into ActiveRecord is really simple and has
low risk of breaking in the future. The cost is that there are a bunch of deleted tables in the database that need to be
maintained. For example, if the table adds a column in a future migration, then the deleted table needs that column as
well.
This turns out to be easy to solve. 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>
---+ Unit tests
A model's soft delete capabilities can be unit tests easily by using some provide asserts.
<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>
=== TODO ===
make undestroying easier when there are lots of related rows to undestroy.





