GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Description: Rails Plugin - soft-delete your ActiveRecord records with a deleted_at timestamp. This is a much more explicit version of ActsAsParanoid
Homepage: http://6brand.com
Clone URL: git://github.com/JackDanger/permanent_records.git
permanent_records / lib / permanent_records.rb
100644 87 lines (72 sloc) 2.391 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
module PermanentRecords
 
  def self.included(base)
    if base.respond_to?(:named_scope)
      base.named_scope :deleted, :conditions => {:deleted_at => true}
      base.named_scope :not_deleted, :conditions => { :deleted_at => nil }
    else
      base.extend LegacyScopes
    end
    base.send :include, InstanceMethods
    base.define_callbacks :before_revive, :after_revive
    base.alias_method_chain :destroy, :permanent_record_force
    base.alias_method_chain :destroy_without_callbacks, :permanent_record
  end
  
  module LegacyScopes
    def with_deleted
      with_scope :find => {:conditions => "#{quoted_table_name}.deleted_at IS NOT NULL"} do
        yield
      end
    end
    
    def with_not_deleted
      with_scope :find => {:conditions => "#{quoted_table_name}.deleted_at IS NULL"} do
        yield
      end
    end
    
    # this next bit is basically stolen from the scope_out plugin
    [:deleted, :not_deleted].each do |name|
      define_method "find_#{name}" do |*args|
        send("with_#{name}") { find(*args) }
      end
 
      define_method "count_#{name}" do |*args|
        send("with_#{name}") { count(*args) }
      end
 
      define_method "calculate_#{name}" do |*args|
        send("with_#{name}") { calculate(*args) }
      end
 
      define_method "find_all_#{name}" do |*args|
        send("with_#{name}") { find(:all, *args) }
      end
    end
  end
  
  module InstanceMethods
    
    def is_permanent?
      respond_to?(:deleted_at)
    end
    
    def deleted?
      deleted_at if is_permanent?
    end
    
    def revive
      run_callbacks :before_revive
      set_deleted_at nil
      run_callbacks :after_revive
      self
    end
    
    def set_deleted_at(value)
      return self unless is_permanent?
      record = self.class.find(id)
      record.update_attribute(:deleted_at, value)
      @attributes, @attributes_cache = record.attributes, record.attributes
    end
    
    def destroy_with_permanent_record_force(force = nil)
      @force_permanent_record_destroy = (:force == force)
      destroy_without_permanent_record_force
    end
    
    def destroy_without_callbacks_with_permanent_record
      return destroy_without_callbacks_without_permanent_record if @force_permanent_record_destroy || !is_permanent?
      unless deleted? || new_record?
        set_deleted_at Time.now
      end
      self
    end
  end
end