New to Rails 3? Check out the Ruby on Rails 3 Tutorial book and screencast.

A book and screencast series showing you how to develop and deploy industrial-strength Rails apps in a direct, step by step way. The screencast series includes 12 lessons over more than 15 hours! Get the best "over the shoulder" experience of following what a top Rails 3 developer does when building an app today. Click here to learn more.

3 Plugins for Safer ActiveRecord Deletions

In Plugins

600px-Gnome-fs-trash-full_EK.svg.pngIt's a fairly common requirement for Rails applications: allow the user to delete data but provide some sort of safety valve so that it can be restored. After all, users make mistakes, and one mistaken deletion can ruin your whole day. Although ActiveRecord itself doesn't directly address this scenario, Rails developers have the choice of several plugins to handle it.

acts_as_paranoid - flags items as deleted in situ

The grandfather of them all is acts_as_paranoid. acts_as_paranoid takes the approach of adding a deleted_at attribute to your model, and overriding ActiveRecord#destroy to set that attribute instead of actually deleting the record. It then overrides ActiveRecord#find to hide the pseudo-deleted records. Unfortunately this code is a little long in the tooth, and may not play nicely with recent Rails releases.

acts_as_soft_deletable - moves deleted items to a different table

acts_as_soft_deletable takes a different approach. Instead of keeping the records in the table and flagging them (which ends up requiring quite a bit of messing around with ActiveRecord internals), it wraps the destroy method and uses it to move rows to a special table instead. On the plus side, this is less intrusive, and may result in better performance when dealing with the "real" data table, since it won't be littered with deleted records. On the minus side, it commits you to maintaining two tables for each entity, and keeping them in sync.

acts_as_trashable - serializes deleted data to a "trash" table

You can see a third approach to this problem in acts_as_trashable. This one maintains a single "trash" table into which it serializes any data you delete (at least, for models that are declared to be trashable). The nicest feature here is that the serialization includes any deleted associated child records. acts_as_trashable also includes support for taking out the trash to reduce the size of the trash table.

Depending on your version of Rails, you may find rough edges with any of these three approaches. Best bet: decide which approach feels best for your own particular data needs, and then carefully test before deploying.

Support from: 1st Easy offers UK Rails hosting (dedicated and shared) running Phusion Passenger (mod_rails) and LAMP stack. If you want to get to know us first, or simply want to evaluate the performance of your Rails applications running on Passenger, we'll arrange a trial hosting account for you (full technical support included!)

Post to Twitter Tweet This Post

Vaguely Related Posts (Usually)

7 Comment Responses to “3 Plugins for Safer ActiveRecord Deletions”

  1. #1
    Josh N. Abbott Says:

    Thanks for the post! I've been looking for a neat little write-up like this.

    -- Josh

  2. #2
    Jan Says:

    It would be nice if you can tell the reason why acts_as_paranoid won't work well with latest Rails.

  3. #3
    grosser Says:

    Thanks for the comparison, i always wondered if there are other aproaches out there.

    Imo soft-deleteable is superior to paranoid, the little extra migration overhead is worth it...

    Trashable seems nice, but when the user is too old recovery could get hard (rows missing/validations failing) but keeping the deleted childs seems promissing...

  4. #4
    Marcel Says:

    Thanks for the write-up! However, could you (or anyone else who has experience with these plugins) tell me something about the ease of restoring data from the three aforementioned mechanisms?

    Keeping a backup of AR-data is one thing, but how do you restore this data when needed and how much effort does it take?

  5. #5
    grosser Says:

    1 and 2 should be easy, but 3 could get hard when your data is out of date...

  6. #6
    jerome Says:

    @marcel: just use recover! class method with acts_as_paranoid

  7. #7
    Garry Tan Says:

    Acts as paranoid doesn't work properly as of Rails 2.1.2 (the last known working version that I have in production is with Rails 2.1.0)

    The problem in 2.1.2 is that something must have changed in the rails code to cause deleted items to appear again in associations. I'm in the process of ripping out Acts as Paranoid now. It should not be used at all and should probably be deprecated entirely with strong warnings to avoid use.

Leave a Reply