technicalpickles

Open Source ProjectsCode that Might be Useful to You

Talks I've GivenOn Technologies and Ideas

ThoughtsWhere I Sometimes Write Things

Resume If You Believe In Those

Follow Me On

GitHubIf coding is your thing

TwitterIf you tweet

Embracing your paranoia with acts_as_paranoid


According to their RDoc, “Overrides some basic methods for the current model so that calling destroy sets a ‘deleted_at’ field to the current timestamp. ActiveRecord is required.”

There doesn’t seem to be really good up-to-date documentation on how to actually use it though. Let’s take a stab at it.

Installing

First thing is to install it. I typically use piston to manage them. We need the at least version 1.9.x for its git support.

myapp $ cd vendor/plugins
myapp/vendor/gems $  piston import git://github.com/technoweenie/acts_as_paranoid.git
INFO main: Guessing the repository type
INFO main: Guessing the working copy type
INFO main: Checking out the repository
INFO main: Copying from Piston::Revision(git://github.com/technoweenie/acts_as_paranoid.git@1e9144e483524b4f246a1768462eadb22f634f19)
INFO main: Checked out "git://github.com/technoweenie/acts_as_paranoid.git" 1e9144e to "acts_as_paranoid"

Configuring

We now can define a model class to be paranoid:

class Event < ActiveRecord::Base  
  acts_as_paranoid
end

Internally, acts_as_paranoid uses the deleted_at column to track if something is deleted or not. So, we need to make a migration for it:

myapp $ script/generate migration MakeEventParanoid
  exists  db/migrate
  create  db/migrate/012_make_event_paranoid.rb

It should look something like:

class MakeEventParanoid &lt; ActiveRecord::Migration
  def self.up
    add_column :events, :deleted_at, :datetime
  end

  def self.down
    remove_column :events, :deleted_at
  end
end

You can now migrate:

myapp $ rake db:migrate
== 12 AddDeletedAt: migrating =================================================
-- add_column("events", :deleted_at, :datetime)
   -> 0.3596s
== 12 AddDeletedAt: migrated (0.3596s) ========================================

Using

It might be easiest to demonstrate with this snippet from script/console:

>> event = Event.find(:first)
=> #<Event id: 91133883, date: "2008-04-28 00:00:00", description: "The Ezra event tonight has been cancelled.The Ezra ...", created_at: "2008-04-16 13:30:20", updated_at: "2008-05-30 23:43:22", location: "", lng: nil, lat: nil, title: "Meeting", deleted_at: nil>
>> event.destroy!
=> #<Event id: 91133883, date: "2008-04-28 00:00:00", description: "The Ezra event tonight has been cancelled.The Ezra ...", created_at: "2008-04-16 13:30:20", updated_at: "2008-05-30 23:43:22", location: "", lng: nil, lat: nil, title: "Meeting", deleted_at: nil>
>> Event.find(:first)
=> #<Event id: 420662881, date: "2008-04-15 00:00:00", description: "Worked on creating the app for this site, [bostonrb...", created_at: "2008-04-16 13:30:20", updated_at: "2008-05-29 01:19:41", location: nil, lng: nil, lat: nil, title: "Hackfest", deleted_at: nil>
>> Event.find_with_deleted(:first)
=> #<Event id: 420662881, date: "2008-04-15 00:00:00", description: "Worked on creating the app for this site, [bostonrb...", created_at: "2008-04-16 13:30:20", updated_at: "2008-05-29 01:19:41", location: nil, lng: nil, lat: nil, title: "Hackfest", deleted_at: nil>
>> event.deleted_at = nil
=> nil
>> event.save!
=> true
>> Event.find(:first)
=> #<Event id: 420662881, date: "2008-04-15 00:00:00", description: "Worked on creating the app for this site, [bostonrb...", created_at: "2008-04-16 13:30:20", updated_at: "2008-05-29 01:19:41", location: nil, lng: nil, lat: nil, title: "Hackfest", deleted_at: nil>

A synopsis:

  • Find the first event
  • Delete it
  • Find the first event again, and see that it’s something else
  • Find with deleted records, to see our original event
  • Unset deleted_at to ‘undelete’ the orignal event.

Update: Fixed the script/console section. Was using the wrong variable that I used earlier in the IRB session, but wasn’t displayed.

comments powered by Disqus