Module: Auditable::Auditing::ClassMethods

Defined in:
lib/auditable/auditing.rb

Instance Method Summary collapse

Instance Method Details

#audit(*args) ⇒ Object

Set the list of methods to track over record saves

Example:

class Survey < ActiveRecord::Base
  audit :page_count, :question_ids
end


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/auditable/auditing.rb', line 118

def audit(*args)

  options = args.extract_options!

  # Setup callbacks
  callback = options.delete(:after_create)
  self.audited_after_create = callback if callback
  callback = options.delete(:after_update)
  self.audited_after_update = callback if callback

  # setup changed_by
  changed_by = options.delete(:changed_by)

  if changed_by.is_a?(String) || changed_by.is_a?(Symbol) || changed_by.respond_to?(:call)
    set_audited_cache('changed_by', changed_by)

  # If inherited from parent's changed_by, do nothing
  elsif audited_cache('changed_by')
    # noop

  # Otherwise create the default changed_by methods and set configuration in cache.
  else
    set_audited_cache('changed_by', :changed_by )
    define_method(:changed_by) { @changed_by }
    define_method(:changed_by=) { |change| @changed_by = change }
  end

  options[:class_name] ||= "Auditable::Audit"
  options[:as] = :auditable

  self.audited_version = options.delete(:version)

  has_many :audits, options

  if self.audited_after_create
    after_create self.audited_after_create
  else
    after_create :audit_create_callback
  end

  if self.audited_after_update
    after_update self.audited_after_update
  else
    after_update :audit_update_callback
  end

  self.audited_attributes = Array.wrap args
end

#audited_after_createObject



28
29
30
# File 'lib/auditable/auditing.rb', line 28

def audited_after_create
  audited_cache('after_create')
end

#audited_after_create=(after_create) ⇒ Object



32
33
34
35
36
37
38
39
40
# File 'lib/auditable/auditing.rb', line 32

def audited_after_create=(after_create)
  set_audited_cache('after_create', after_create) do |parent_class, callback|

    # Disable the inherited audit create callback
    skip_callback(:create, :after, parent_class.audited_after_create)

    callback
  end
end

#audited_after_updateObject



42
43
44
# File 'lib/auditable/auditing.rb', line 42

def audited_after_update
  audited_cache('after_update')
end

#audited_after_update=(after_update) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'lib/auditable/auditing.rb', line 46

def audited_after_update=(after_update)
  set_audited_cache('after_update', after_update) do |parent_class, callback|

    # Disable the inherited audit create callback
    skip_callback(:update, :after, parent_class.audited_after_update)

    callback
  end
end

#audited_attributesObject

Get the list of methods to track over record saves, including those inherited from parent



8
9
10
11
12
# File 'lib/auditable/auditing.rb', line 8

def audited_attributes
  audited_cache('attributes') do |parent_class, attrs|
    (attrs || []).push(*parent_class.audited_attributes)
  end
end

#audited_attributes=(attributes) ⇒ Object



14
15
16
17
18
# File 'lib/auditable/auditing.rb', line 14

def audited_attributes=(attributes)
  set_audited_cache( 'attributes', attributes ) do |parent_class, attrs|
    attrs.push(*parent_class.audited_attributes)
  end
end

#audited_cache(key, &blk) ⇒ Object

Get the configuration of Auditable. Check the parent class for the configuration if it does not exist in the implementing class.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/auditable/auditing.rb', line 76

def audited_cache( key, &blk )

  # init the cache, since child classes may not declare audit
  @audited_cache ||= {}.with_indifferent_access
  topic =  @audited_cache[key]

  # Check the parent for a val
  if topic.nil? && superclass != ActiveRecord::Base && superclass.respond_to?(:audited_cache)
    begin
      if block_given?
          topic = yield( superclass, topic )
      else
        topic = superclass.audited_cache( key )
      end
    rescue
      raise "Failed to create audit for #{self.name} accessing parent #{superclass.name} - #{$!}"
    end

    # Set cache explicitly to false if the result was nil
    if topic.nil?
      topic = @audited_cache[key] = false

    # Coerce to symbol if a string
    elsif topic.is_a? String
      topic = @audited_cache[key] = topic.to_sym

    # Otherwise set the cache straight up
    else
      @audited_cache[key] = topic
    end
  end

  topic
end

#audited_versionObject



20
21
22
# File 'lib/auditable/auditing.rb', line 20

def audited_version
  audited_cache('version')
end

#audited_version=(version) ⇒ Object



24
25
26
# File 'lib/auditable/auditing.rb', line 24

def audited_version=(version)
  set_audited_cache( 'version', version )
end

#set_audited_cache(key, val, &blk) ⇒ Object

Set the configuration of Auditable. Optional block to access the parent class configuration setting.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/auditable/auditing.rb', line 57

def set_audited_cache(key,val,&blk)

  if superclass != ActiveRecord::Base && superclass.respond_to?(:audited_cache)
    if block_given?
      begin
        val = yield( superclass, val )
      rescue
        raise "Failed to create audit for #{self.name} accessing parent #{superclass.name} - #{$!}"
      end
    end
  end

  # init the cache, since child classes may not declare audit
  @audited_cache ||= {}.with_indifferent_access
  @audited_cache[key] = val
end