Recipe 14.10. Disabling Records Instead of Deleting Them with acts_as_paranoid


Recipe 14.10. Disabling Records Instead of Deleting Them with acts_as_paranoid

Problem

You have an application with user accounts where users periodically need to be deleted. You'd like to add a flag to the users table that allows you to inactivate users without deleting them permanently. Instead of modifying all your existing and future code, you want Active Record to do this for you.

Solution

Use the acts_as_paranoid plug-in to override Active Record's find, count, and destroy methods. This plug-in requires that the tables you apply it to have a deleted_at column of type :datetime.

db/migrate/001_create_users.rb:

class CreateUsers < ActiveRecord::Migration   def self.up     create_table "users", :force => true do |t|       t.column :login,            :string, :limit => 40       t.column :email,            :string, :limit => 100       t.column :deleted_at,       :datetime     end   end   def self.down     drop_table "users"    end end

To apply the plug-in to the User model, add acts_as_paranoid to the model definition:

app/models/user.rb:

class User < ActiveRecord::Base   acts_as_paranoid end

Now the destroy method of User objects no longer deletes objects from the database. Instead, the object's deleted_at field is set to the current date and time, and the behavior of the find method is changed (or overridden) to retrieve only records where the deleted_at field has not be set. For example, @user.destroy actually executes the following SQL query:

UPDATE users SET deleted_at = '2006-06-02 22:05:51' WHERE (id = 6)

This action User.find(6) performs:

SELECT * FROM users WHERE (users.deleted_at IS NULL OR    users.deleted_at > '2006-06-02 22:07:20') AND (users.id = 6) LIMIT 1

Discussion

Data in your database is valuable. Once you've gathered data, you don't want to lose it. Storage space is cheap, and data about users that were once active can be just as important as data about currently active users. In other words, permanently purging data is like losing a part of your application's history. You may not think you need that data initially, but often data becomes more valuable as it accumulates over time. You never know what kind of reporting you'll want to do in the future.

So in the name of preserving data, inactivate what you might otherwise have deleted. This plug-in makes setting up the behavior for your models easy. With acts_as_paranoid, the details of how Active Record manages "deleted" objects are transparent to the code that's manipulating users.

Although the plug-in overrides the behavior of find and count to ignore records with a deleted_at date, additional variations on these methods are provided to query and count all records in the database, including those that have been inactivated. For example User.find_with_deleted(:all) returns an array of all User objects, and User.count_with_deleted returns the total number of User objects. Here's how to return a specific User object, regardless of whether it's been inactivated, with an id of 4:

User.find_with_deleted(4)

See Also

  • Section 14.6"




Rails Cookbook
Rails Cookbook (Cookbooks (OReilly))
ISBN: 0596527314
EAN: 2147483647
Year: 2007
Pages: 250
Authors: Rob Orsini

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net