acts_as_audited_customized 1.2.2 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -7,7 +7,7 @@ The purpose of this fork is to store both the previous values and the changed va
7
7
  == Installation
8
8
 
9
9
  * acts_as_audited can be installed as a gem:
10
-
10
+
11
11
  # config/environment.rb
12
12
  config.gem 'acts_as_audited', :lib => false, :source => 'http://gemcutter.org'
13
13
 
@@ -26,7 +26,7 @@ Declare <tt>acts_as_audited</tt> on your models:
26
26
  class User < ActiveRecord::Base
27
27
  acts_as_audited :except => [:password, :mistress]
28
28
  end
29
-
29
+
30
30
  Within a web request, will automatically record the user that made the change if your controller has a <tt>current_user</tt> method.
31
31
 
32
32
  To record a user in the audits outside of a web request, you can use <tt>as_user</tt>:
@@ -44,6 +44,10 @@ If your model declares +attr_accessible+ after +acts_as_audited+, you need to se
44
44
  attr_accessible :name
45
45
  end
46
46
 
47
+ 12/21/10:
48
+
49
+ There have been no tests written for any of the new features. There's just been no time.
50
+
47
51
  == Compatability
48
52
 
49
53
  acts_as_audited works with Rails 2.1 or later.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.2
1
+ 1.3.1
@@ -37,6 +37,16 @@ module CollectiveIdea #:nodoc:
37
37
  mattr_accessor :human_model
38
38
  @@human_model = :user
39
39
 
40
+ # Any additional attributes you wish your model to write to. Default: []
41
+ mattr_accessor :additional_attributes
42
+ @@additional_attributes = []
43
+
44
+ # Whether or not you want to use the Observer to set current_<%= human_model %>.
45
+ # Set this to :false if your models have access to the current_<%= human_model %> method.
46
+ # Default :true
47
+ mattr_accessor :use_observer
48
+ @@use_observer = :true
49
+
40
50
  class << self
41
51
  # Call this method to modify defaults in your initializers.
42
52
  #
@@ -46,6 +56,36 @@ module CollectiveIdea #:nodoc:
46
56
  # end
47
57
  def configure
48
58
  yield self
59
+
60
+ modify_audit_model
61
+ end
62
+
63
+ def modify_audit_model
64
+ Audit.class_eval do
65
+ belongs_to @@human_model, :polymorphic => true
66
+
67
+ [@@additional_attributes].flatten.each do |attrib|
68
+ belongs_to attrib, :class_name => @@human_model.to_s.classify, :foreign_key => "#{attrib}_id"
69
+ end
70
+
71
+ alias_method :user_as_model=, "#{@@human_model}=".to_sym
72
+ alias_method "#{@@human_model}=".to_sym, :user_as_string=
73
+
74
+ alias_method :user_as_model, @@human_model
75
+ alias_method @@human_model, :user_as_string
76
+
77
+ def set_audit_user
78
+ self.send(@@human_model, Thread.current[:acts_as_audited_user]) if Thread.current[:acts_as_audited_user]
79
+ nil # prevent stopping callback chains
80
+ end
81
+ end
82
+
83
+ if @@use_observer
84
+ ::ActionController::Base.class_eval do
85
+ cache_sweeper :audit_sweeper
86
+ end
87
+ Audit.add_observer(AuditSweeper.instance)
88
+ end
49
89
  end
50
90
 
51
91
  def included(base) # :nodoc:
@@ -81,10 +121,14 @@ module CollectiveIdea #:nodoc:
81
121
  # don't allow multiple calls
82
122
  return if self.included_modules.include?(CollectiveIdea::Acts::Audited::InstanceMethods)
83
123
 
124
+ reserved_options = [:protect, :on, :create, :update, :destroy, :only, :except, :if, :unless]
84
125
  options = {:protect => accessible_attributes.nil?}.merge(options)
85
126
 
86
127
  class_inheritable_reader :non_audited_columns
87
128
  class_inheritable_reader :auditing_enabled
129
+ class_inheritable_reader :manually_set_columns
130
+ class_inheritable_reader :if_condition
131
+ class_inheritable_reader :unless_condition
88
132
 
89
133
  if options[:only]
90
134
  except = self.column_names - options[:only].flatten.map(&:to_s)
@@ -94,6 +138,9 @@ module CollectiveIdea #:nodoc:
94
138
  except |= Array(options[:except]).collect(&:to_s) if options[:except]
95
139
  end
96
140
  write_inheritable_attribute :non_audited_columns, except
141
+ write_inheritable_attribute :manually_set_columns, options.reject {|k, v| reserved_options.include?(k) }
142
+ write_inheritable_attribute :if_condition, options.delete(:if)
143
+ write_inheritable_attribute :unless_condition, options.delete(:unless)
97
144
 
98
145
  has_many :audits, :as => :auditable, :order => "#{Audit.quoted_table_name}.version"
99
146
  attr_protected :audit_ids if options[:protect]
@@ -187,6 +234,43 @@ module CollectiveIdea #:nodoc:
187
234
  end
188
235
  end
189
236
 
237
+ def evaluate(value)
238
+ case value
239
+ when Proc
240
+ value.arity > 0 ? value.call(self) : value.call
241
+ else
242
+ value
243
+ end
244
+ end
245
+
246
+ def on_behalf_of_result
247
+ evaluate(on_behalf_of_call)
248
+ end
249
+
250
+ def set_manually_set_columns
251
+ manually_set_columns.inject(set_current_user) do |attrs, (attrib, value)|
252
+ attrs[attrib] = evaluate(value)
253
+ attrs
254
+ end
255
+ end
256
+
257
+ def set_current_user
258
+ method = "current_#{CollectiveIdea::Acts::Audited.human_model}"
259
+ !CollectiveIdea::Acts::Audited.use_observer && self.class.respond_to?(method) ? { CollectiveIdea::Acts::Audited.human_model => self.class.send(method) } : {}
260
+ end
261
+
262
+ def eval_condition(condition)
263
+ evaluate(condition)
264
+ end
265
+
266
+ def eval_if_condition
267
+ !if_condition || eval_condition(if_condition)
268
+ end
269
+
270
+ def eval_unless_condition
271
+ !unless_condition || !eval_condition(unless_condition)
272
+ end
273
+
190
274
  def audits_to(version = nil)
191
275
  if version == :previous
192
276
  version = if self.version
@@ -215,7 +299,8 @@ module CollectiveIdea #:nodoc:
215
299
  end
216
300
 
217
301
  def write_audit(attrs)
218
- self.audits.create attrs if auditing_enabled
302
+ attrs = attrs.merge(set_manually_set_columns)
303
+ self.audits.create attrs if auditing_enabled && eval_if_condition && eval_unless_condition
219
304
  end
220
305
  end # InstanceMethods
221
306
 
@@ -251,7 +336,6 @@ module CollectiveIdea #:nodoc:
251
336
  def audit_as( user, &block )
252
337
  Audit.as_user( user, &block )
253
338
  end
254
-
255
339
  end
256
340
  end
257
341
  end
@@ -3,16 +3,17 @@ require 'set'
3
3
  # Audit saves the changes to ActiveRecord models. It has the following attributes:
4
4
  #
5
5
  # * <tt>auditable</tt>: the ActiveRecord model that was changed
6
- # * <tt><%= human_model %></tt>: the <%= human_model %> that performed the change; a string or an ActiveRecord model
6
+ # * <tt>user</tt>: the user that performed the change; a string or an ActiveRecord model
7
7
  # * <tt>action</tt>: one of create, update, or delete
8
8
  # * <tt>changes</tt>: a serialized hash of all the changes
9
9
  # * <tt>created_at</tt>: Time that the change was performed
10
10
  #
11
11
  class Audit < ActiveRecord::Base
12
12
  belongs_to :auditable, :polymorphic => true
13
- belongs_to :<%= human_model %>, :polymorphic => true
13
+ # belongs_to :user, :polymorphic => true
14
+ # belongs_to :on_behalf_of, :class_name => 'User', :foreign_key => 'on_behalf_of_id'
14
15
 
15
- before_create :set_version_number, :set_audit_<%= human_model %>
16
+ before_create :set_version_number, :set_audit_user
16
17
 
17
18
  serialize :changes
18
19
 
@@ -28,19 +29,19 @@ class Audit < ActiveRecord::Base
28
29
  # by +user+. This method is hopefully threadsafe, making it ideal
29
30
  # for background operations that require audit information.
30
31
  def as_user(user, &block)
31
- Thread.current[:acts_as_audited_<%= human_model %>] = user
32
+ Thread.current[:acts_as_audited_user] = user
32
33
  yield
33
- Thread.current[:acts_as_audited_<%= human_model %>] = nil
34
+ Thread.current[:acts_as_audited_user] = nil
34
35
  end
35
36
 
36
- def manual_audit(<%= human_model %>, action, auditable = nil)
37
+ def manual_audit(user, action, on_behalf_of = nil, auditable = nil)
37
38
  attribs = { :action => action }
38
39
 
39
- case <%= human_model %>
40
+ case user
40
41
  when ActiveRecord::Base
41
- attribs[:<%= human_model %>] = <%= human_model %>
42
+ attribs[CollectiveIdea::Acts::Audited.human_model] = user
42
43
  when String
43
- attribs[:username] = <%= human_model %>
44
+ attribs[:username] = user
44
45
  end
45
46
 
46
47
  case auditable
@@ -50,26 +51,27 @@ class Audit < ActiveRecord::Base
50
51
  attribs[:auditable_type] = auditable
51
52
  end
52
53
 
54
+ attribs[:on_behalf_of] = on_behalf_of if on_behalf_of
53
55
  Audit.create attribs
54
56
  end
55
57
  end
56
58
 
57
- # Allows <%= human_model %> to be set to either a string or an ActiveRecord object
58
- def <%= human_model %>_as_string=(<%= human_model %>) #:nodoc:
59
+ # Allows user to be set to either a string or an ActiveRecord object
60
+ def user_as_string=(user) #:nodoc:
59
61
  # reset both either way
60
- self.<%= human_model %>_as_model = self.username = nil
61
- <%= human_model %>.is_a?(ActiveRecord::Base) ?
62
- self.<%= human_model %>_as_model = <%= human_model %> :
63
- self.username = <%= human_model %>
62
+ self.user_as_model = self.username = nil
63
+ user.is_a?(ActiveRecord::Base) ?
64
+ self.user_as_model = user :
65
+ self.username = user
64
66
  end
65
- alias_method :<%= human_model %>_as_model=, :<%= human_model %>=
66
- alias_method :<%= human_model %>=, :<%= human_model %>_as_string=
67
+ # alias_method :user_as_model=, :user=
68
+ # alias_method :user=, :user_as_string=
67
69
 
68
- def <%= human_model %>_as_string #:nodoc:
69
- self.<%= human_model %>_as_model || self.username
70
+ def user_as_string #:nodoc:
71
+ self.user_as_model || self.username
70
72
  end
71
- alias_method :<%= human_model %>_as_model, :<%= human_model %>
72
- alias_method :<%= human_model %>, :<%= human_model %>_as_string
73
+ # alias_method :user_as_model, :user
74
+ # alias_method :user, :user_as_string
73
75
 
74
76
  def revision
75
77
  clazz = auditable_type.constantize
@@ -131,9 +133,9 @@ private
131
133
  self.version = max + 1
132
134
  end
133
135
 
134
- def set_audit_<%= human_model %>
135
- self.<%= human_model %> = Thread.current[:acts_as_audited_<%= human_model %>] if Thread.current[:acts_as_audited_<%= human_model %>]
136
- nil # prevent stopping callback chains
137
- end
136
+ # def set_audit_user
137
+ # self.user = Thread.current[:acts_as_audited_user] if Thread.current[:acts_as_audited_user]
138
+ # nil # prevent stopping callback chains
139
+ # end
138
140
 
139
141
  end
@@ -19,19 +19,22 @@ module CollectiveIdea #:nodoc:
19
19
  end
20
20
  end
21
21
 
22
+ ActionController::Base.class_eval do
23
+ extend CollectiveIdea::ActionController::Audited
24
+ end
25
+
22
26
  class AuditSweeper < ActionController::Caching::Sweeper #:nodoc:
27
+ def current_user_method
28
+ "current_#{CollectiveIdea::Acts::Audited.human_model}".to_sym
29
+ end
30
+
23
31
  def before_create(audit)
24
- audit.send("#{CollectiveIdea::Acts::Audited.human_model}=", current_user) unless audit.send(CollectiveIdea::Acts::Audited.human_model)
32
+ raise "Got here"
33
+ audit.send("#{CollectiveIdea::Acts::Audited.human_model}=".to_sym, current_user) unless audit.send(CollectiveIdea::Acts::Audited.human_model)
25
34
  end
26
35
 
27
36
  def current_user
28
- method = "current_#{CollectiveIdea::Acts::Audited.human_model}"
29
- controller.send(method) if controller.respond_to?(method, true)
37
+ controller.send current_user_method if controller.respond_to?(current_user_method, true)
30
38
  end
31
39
  end
32
40
 
33
- ActionController::Base.class_eval do
34
- extend CollectiveIdea::ActionController::Audited
35
- cache_sweeper :audit_sweeper
36
- end
37
- Audit.add_observer(AuditSweeper.instance)
data/rails/init.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'acts_as_audited/audit'
1
2
  require 'acts_as_audited'
2
3
 
3
4
  ActiveRecord::Base.send :include, CollectiveIdea::Acts::Audited
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_audited_customized
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 2
9
- - 2
10
- version: 1.2.2
8
+ - 3
9
+ - 1
10
+ version: 1.3.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Brandon Keepers
@@ -77,14 +77,12 @@ files:
77
77
  - README
78
78
  - Rakefile
79
79
  - VERSION
80
- - generators/audit_model/USAGE
81
- - generators/audit_model/audit_model_generator.rb
82
- - generators/audit_model/templates/model.rb
83
80
  - generators/audited_migration/USAGE
84
81
  - generators/audited_migration/audited_migration_generator.rb
85
82
  - generators/audited_migration/templates/migration.rb
86
83
  - init.rb
87
84
  - lib/acts_as_audited.rb
85
+ - lib/acts_as_audited/audit.rb
88
86
  - lib/acts_as_audited/audit_sweeper.rb
89
87
  - rails/init.rb
90
88
  - test/acts_as_audited_test.rb
@@ -1,9 +0,0 @@
1
- Description:
2
- The audit model generator creates the Audit model in app/models/ associating it with the correct "human" class ("user" by default).
3
-
4
- Example:
5
- ./script/generate audit_model Person
6
-
7
- This will create the Audit model in app/models/ associating it to the Person model.
8
-
9
- You must generate the migration using the same "human" class.
@@ -1,20 +0,0 @@
1
- class AuditModelGenerator < Rails::Generator::NamedBase
2
- def initialize(runtime_args, runtime_options = {})
3
- runtime_args << 'user' if runtime_args.empty?
4
- super
5
- @human_model = runtime_args[0] ? runtime_args[0].underscore : 'user'
6
- end
7
-
8
- def manifest
9
- record do |m|
10
- m.directory(File.join('app', 'models'))
11
- m.template('model.rb', "app/models/audit.rb", :assigns => { :human_model => @human_model })
12
- end
13
- end
14
-
15
- protected
16
-
17
- def banner
18
- "Usage: #{$0} audit_model [human_model_name]"
19
- end
20
- end