track_changes 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -20
- data/README.rdoc +87 -87
- data/TODO +4 -4
- data/VERSION.yml +5 -5
- data/lib/track_changes/audit_filter.rb +69 -69
- data/lib/track_changes/base.rb +9 -9
- data/lib/track_changes/class_methods.rb +74 -74
- data/lib/track_changes/configuration.rb +38 -38
- data/lib/track_changes/filter.rb +43 -43
- data/lib/track_changes/initializer.rb +18 -18
- data/lib/track_changes/instance_methods.rb +5 -5
- data/lib/track_changes/result.rb +36 -36
- data/lib/track_changes.rb +12 -12
- data/test/base_test.rb +20 -20
- data/test/class_methods_test.rb +29 -29
- data/test/filter_test.rb +73 -73
- data/test/functional/posts_controller_test.rb +16 -16
- data/test/rails_root/app/controllers/application_controller.rb +2 -2
- data/test/rails_root/app/controllers/posts_controller.rb +36 -36
- data/test/rails_root/app/models/audit.rb +4 -4
- data/test/rails_root/app/models/post.rb +3 -3
- data/test/rails_root/config/boot.rb +110 -110
- data/test/rails_root/config/database.yml +3 -3
- data/test/rails_root/config/environment.rb +7 -7
- data/test/rails_root/config/environments/test.rb +7 -7
- data/test/rails_root/config/initializers/new_rails_defaults.rb +7 -7
- data/test/rails_root/config/initializers/session_store.rb +4 -4
- data/test/rails_root/config/initializers/track_changes_setup.rb +8 -8
- data/test/rails_root/config/routes.rb +3 -3
- data/test/rails_root/db/migrate/20100115021125_create_audits.rb +16 -16
- data/test/rails_root/db/migrate/20100115021151_create_posts.rb +15 -15
- data/test/rails_root/log/test.log +377 -2494
- data/test/rails_root/script/console +3 -3
- data/test/rails_root/script/generate +3 -3
- data/test/result_test.rb +35 -35
- data/test/test_helper.rb +29 -29
- data/test/track_changes/audit_filter_test.rb +154 -154
- data/test/track_changes/configuration_test.rb +36 -36
- data/test/track_changes/initializer_test.rb +37 -37
- metadata +31 -19
data/LICENSE
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
Copyright (c) 2008-2010 Matt Haley
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
|
+
Copyright (c) 2008-2010 Matt Haley
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
CHANGED
@@ -1,87 +1,87 @@
|
|
1
|
-
= track_changes
|
2
|
-
|
3
|
-
TrackChanges is a Rails plugin to facilitate tracking
|
4
|
-
changes made to an ActiveRecord model in your
|
5
|
-
Controller actions.
|
6
|
-
|
7
|
-
== Why?
|
8
|
-
|
9
|
-
I originally looked at the available auditing solutions
|
10
|
-
and it appeared that most of them were not thread-safe.
|
11
|
-
|
12
|
-
== Installation
|
13
|
-
|
14
|
-
gem install track_changes
|
15
|
-
|
16
|
-
== Configuration
|
17
|
-
|
18
|
-
You need to have an Audit class that has a polymorphic
|
19
|
-
<tt>belongs_to</tt> association to <tt>:audited</tt>. In
|
20
|
-
addition, the Audit model must have a <tt>user</tt>
|
21
|
-
attribute, and your controllers must respond to
|
22
|
-
<tt>current_user</tt>.
|
23
|
-
|
24
|
-
Example Audit class:
|
25
|
-
|
26
|
-
class Audit < ActiveRecord::Base
|
27
|
-
belongs_to :audited, :polymorphic => true
|
28
|
-
serialize :change_set
|
29
|
-
end
|
30
|
-
|
31
|
-
Example Audited class:
|
32
|
-
|
33
|
-
class Post < ActiveRecord::Base
|
34
|
-
has_many :audits, :as => :audited
|
35
|
-
end
|
36
|
-
|
37
|
-
You can also tweak some of the defaults by creating an initializer
|
38
|
-
in <tt>RAILS_ROOT/config/initializers/track_changes_configuration.rb</tt>
|
39
|
-
and calling TrackChanges::Initializer.instance which yields a
|
40
|
-
TrackChanges::Configuration object:
|
41
|
-
|
42
|
-
# These are the defaults anyways
|
43
|
-
TrackChanges::Initializer.instance do |c|
|
44
|
-
c.audit_assocation = :audits # Calls <tt>create!</tt> on this association method
|
45
|
-
c.current_user = :current_user # Controller is sent this method to obtain current user.
|
46
|
-
c.ignore_nil = true # Don't crash if a model is nil.
|
47
|
-
end
|
48
|
-
|
49
|
-
== Controller Example
|
50
|
-
|
51
|
-
In this example, after the `update` action is called,
|
52
|
-
the `@post` will be compared to a previous version, and
|
53
|
-
if there are any changes, an audit will be created.
|
54
|
-
|
55
|
-
class PostController < ApplicationController
|
56
|
-
include TrackChanges
|
57
|
-
|
58
|
-
before_filter :get_post, :except => [:index, :new]
|
59
|
-
|
60
|
-
# specify a single model
|
61
|
-
track_changes :post
|
62
|
-
|
63
|
-
# you can also specify multiple models
|
64
|
-
#track_changes :post1, :post2, ...
|
65
|
-
|
66
|
-
def update
|
67
|
-
if @post.update_attributes(params[:post])
|
68
|
-
flash[:notice] = "Success."
|
69
|
-
else
|
70
|
-
render :action => "edit"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# Normal controller actions
|
75
|
-
# ...
|
76
|
-
|
77
|
-
protected
|
78
|
-
|
79
|
-
def get_post
|
80
|
-
@post = Post.find(params[:id])
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
|
85
|
-
== COPYRIGHT
|
86
|
-
|
87
|
-
Copyright (c) 2008-2010 Matt Haley. See LICENSE for details.
|
1
|
+
= track_changes
|
2
|
+
|
3
|
+
TrackChanges is a Rails plugin to facilitate tracking
|
4
|
+
changes made to an ActiveRecord model in your
|
5
|
+
Controller actions.
|
6
|
+
|
7
|
+
== Why?
|
8
|
+
|
9
|
+
I originally looked at the available auditing solutions
|
10
|
+
and it appeared that most of them were not thread-safe.
|
11
|
+
|
12
|
+
== Installation
|
13
|
+
|
14
|
+
gem install track_changes
|
15
|
+
|
16
|
+
== Configuration
|
17
|
+
|
18
|
+
You need to have an Audit class that has a polymorphic
|
19
|
+
<tt>belongs_to</tt> association to <tt>:audited</tt>. In
|
20
|
+
addition, the Audit model must have a <tt>user</tt>
|
21
|
+
attribute, and your controllers must respond to
|
22
|
+
<tt>current_user</tt>.
|
23
|
+
|
24
|
+
Example Audit class:
|
25
|
+
|
26
|
+
class Audit < ActiveRecord::Base
|
27
|
+
belongs_to :audited, :polymorphic => true
|
28
|
+
serialize :change_set
|
29
|
+
end
|
30
|
+
|
31
|
+
Example Audited class:
|
32
|
+
|
33
|
+
class Post < ActiveRecord::Base
|
34
|
+
has_many :audits, :as => :audited
|
35
|
+
end
|
36
|
+
|
37
|
+
You can also tweak some of the defaults by creating an initializer
|
38
|
+
in <tt>RAILS_ROOT/config/initializers/track_changes_configuration.rb</tt>
|
39
|
+
and calling TrackChanges::Initializer.instance which yields a
|
40
|
+
TrackChanges::Configuration object:
|
41
|
+
|
42
|
+
# These are the defaults anyways
|
43
|
+
TrackChanges::Initializer.instance do |c|
|
44
|
+
c.audit_assocation = :audits # Calls <tt>create!</tt> on this association method
|
45
|
+
c.current_user = :current_user # Controller is sent this method to obtain current user.
|
46
|
+
c.ignore_nil = true # Don't crash if a model is nil.
|
47
|
+
end
|
48
|
+
|
49
|
+
== Controller Example
|
50
|
+
|
51
|
+
In this example, after the `update` action is called,
|
52
|
+
the `@post` will be compared to a previous version, and
|
53
|
+
if there are any changes, an audit will be created.
|
54
|
+
|
55
|
+
class PostController < ApplicationController
|
56
|
+
include TrackChanges
|
57
|
+
|
58
|
+
before_filter :get_post, :except => [:index, :new]
|
59
|
+
|
60
|
+
# specify a single model
|
61
|
+
track_changes :post
|
62
|
+
|
63
|
+
# you can also specify multiple models
|
64
|
+
#track_changes :post1, :post2, ...
|
65
|
+
|
66
|
+
def update
|
67
|
+
if @post.update_attributes(params[:post])
|
68
|
+
flash[:notice] = "Success."
|
69
|
+
else
|
70
|
+
render :action => "edit"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Normal controller actions
|
75
|
+
# ...
|
76
|
+
|
77
|
+
protected
|
78
|
+
|
79
|
+
def get_post
|
80
|
+
@post = Post.find(params[:id])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
== COPYRIGHT
|
86
|
+
|
87
|
+
Copyright (c) 2008-2010 Matt Haley. See LICENSE for details.
|
data/TODO
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Track Changes TODO List
|
2
|
-
=======================
|
3
|
-
|
4
|
-
* Check for ivars
|
1
|
+
Track Changes TODO List
|
2
|
+
=======================
|
3
|
+
|
4
|
+
* Check for ivars
|
data/VERSION.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
---
|
2
|
-
:
|
3
|
-
:
|
4
|
-
:
|
5
|
-
:
|
1
|
+
---
|
2
|
+
:patch: 1
|
3
|
+
:major: 0
|
4
|
+
:build:
|
5
|
+
:minor: 5
|
@@ -1,69 +1,69 @@
|
|
1
|
-
module TrackChanges
|
2
|
-
# An around filter that will audit changes to your models.
|
3
|
-
#
|
4
|
-
# Example:
|
5
|
-
# class OrdersController < ApplicationController
|
6
|
-
# before_filter :find_order, :except => [:index, :new, :create]
|
7
|
-
# around_filter AuditFilter.new(:order), :only => :update
|
8
|
-
#
|
9
|
-
# def update
|
10
|
-
# ...
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
# protected
|
14
|
-
#
|
15
|
-
# def find_order
|
16
|
-
# @order = Order.find(params[:id])
|
17
|
-
# end
|
18
|
-
# end
|
19
|
-
class AuditFilter
|
20
|
-
attr_accessor :cached_models, :models
|
21
|
-
|
22
|
-
def initialize(*models)
|
23
|
-
models.flatten!
|
24
|
-
options = models.extract_options!
|
25
|
-
|
26
|
-
self.cached_models = {}
|
27
|
-
self.models = models
|
28
|
-
|
29
|
-
@audit_accessor = options[:audit_accessor] || :audits
|
30
|
-
@current_user = options[:current_user] || :current_user
|
31
|
-
@ignore_nils = if options[:ignore_nil] == false
|
32
|
-
false
|
33
|
-
else
|
34
|
-
true
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def before(controller)
|
39
|
-
self.models.each do |model|
|
40
|
-
instance_variable_symbol = "@#{model}".to_sym
|
41
|
-
instance = controller.instance_variable_get(instance_variable_symbol)
|
42
|
-
next if instance.nil? && @ignore_nils
|
43
|
-
|
44
|
-
self.cached_models[instance_variable_symbol] = instance.clone
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def after(controller)
|
49
|
-
self.cached_models.each_pair do |instance_variable_symbol, original_instance|
|
50
|
-
new_instance = controller.instance_variable_get(instance_variable_symbol)
|
51
|
-
next if new_instance.changed? # Dirty objects didn't save
|
52
|
-
|
53
|
-
changes = changes_between(new_instance, original_instance)
|
54
|
-
|
55
|
-
unless changes.empty?
|
56
|
-
audit = new_instance.send(@audit_accessor).create!(:user => controller.send(@current_user), :change_set => changes)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def changes_between(new, old)
|
64
|
-
clone = old.clone
|
65
|
-
clone.attributes = new.attributes
|
66
|
-
clone.changes
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
1
|
+
module TrackChanges
|
2
|
+
# An around filter that will audit changes to your models.
|
3
|
+
#
|
4
|
+
# Example:
|
5
|
+
# class OrdersController < ApplicationController
|
6
|
+
# before_filter :find_order, :except => [:index, :new, :create]
|
7
|
+
# around_filter AuditFilter.new(:order), :only => :update
|
8
|
+
#
|
9
|
+
# def update
|
10
|
+
# ...
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# protected
|
14
|
+
#
|
15
|
+
# def find_order
|
16
|
+
# @order = Order.find(params[:id])
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
class AuditFilter
|
20
|
+
attr_accessor :cached_models, :models
|
21
|
+
|
22
|
+
def initialize(*models)
|
23
|
+
models.flatten!
|
24
|
+
options = models.extract_options!
|
25
|
+
|
26
|
+
self.cached_models = {}
|
27
|
+
self.models = models
|
28
|
+
|
29
|
+
@audit_accessor = options[:audit_accessor] || :audits
|
30
|
+
@current_user = options[:current_user] || :current_user
|
31
|
+
@ignore_nils = if options[:ignore_nil] == false
|
32
|
+
false
|
33
|
+
else
|
34
|
+
true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def before(controller)
|
39
|
+
self.models.each do |model|
|
40
|
+
instance_variable_symbol = "@#{model}".to_sym
|
41
|
+
instance = controller.instance_variable_get(instance_variable_symbol)
|
42
|
+
next if instance.nil? && @ignore_nils
|
43
|
+
|
44
|
+
self.cached_models[instance_variable_symbol] = instance.clone
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def after(controller)
|
49
|
+
self.cached_models.each_pair do |instance_variable_symbol, original_instance|
|
50
|
+
new_instance = controller.instance_variable_get(instance_variable_symbol)
|
51
|
+
next if new_instance.changed? # Dirty objects didn't save
|
52
|
+
|
53
|
+
changes = changes_between(new_instance, original_instance)
|
54
|
+
|
55
|
+
unless changes.empty?
|
56
|
+
audit = new_instance.send(@audit_accessor).create!(:user => controller.send(@current_user), :change_set => changes)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def changes_between(new, old)
|
64
|
+
clone = old.clone
|
65
|
+
clone.attributes = new.attributes
|
66
|
+
clone.changes
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/track_changes/base.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require 'track_changes/instance_methods'
|
2
|
-
require 'track_changes/class_methods'
|
3
|
-
|
4
|
-
module TrackChanges
|
5
|
-
def self.included(controller)
|
6
|
-
controller.send(:include, InstanceMethods)
|
7
|
-
controller.extend(ClassMethods)
|
8
|
-
end
|
9
|
-
end
|
1
|
+
require 'track_changes/instance_methods'
|
2
|
+
require 'track_changes/class_methods'
|
3
|
+
|
4
|
+
module TrackChanges
|
5
|
+
def self.included(controller)
|
6
|
+
controller.send(:include, InstanceMethods)
|
7
|
+
controller.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
end
|
@@ -1,74 +1,74 @@
|
|
1
|
-
require 'active_support'
|
2
|
-
require 'track_changes/filter'
|
3
|
-
|
4
|
-
module TrackChanges
|
5
|
-
module ClassMethods
|
6
|
-
# Create an audit of the changes made to a module during a controller action.
|
7
|
-
# Some assumptions are made, primarily that the given models will have a
|
8
|
-
# polymorphic association to an Audit model. An example Audit model:
|
9
|
-
#
|
10
|
-
# class Audit < ActiveRecord::Base
|
11
|
-
# belongs_to :audited, :polymorphic => true
|
12
|
-
# belongs_to :user
|
13
|
-
# serialize :change_set
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# # Example model that would be audited:
|
17
|
-
# class Order < ActiveRecord::Base
|
18
|
-
# has_many :audits, :as => :audited
|
19
|
-
# end
|
20
|
-
#
|
21
|
-
# ==== Parameters
|
22
|
-
#
|
23
|
-
# * A symbol or many symbols of the name(s) of the instance variable to create audits for.
|
24
|
-
# * An optional hash that will be passed as filter conditions to <tt>around_filter</tt>
|
25
|
-
#
|
26
|
-
# ==== Examples
|
27
|
-
#
|
28
|
-
# # Create an audit of changes made to @order during the <tt>:update</tt> action.
|
29
|
-
# track_changes :order
|
30
|
-
#
|
31
|
-
# # Creates an audit of changes made to @order or @customer during the <tt>:update</tt> action.
|
32
|
-
# track_changes :order, :customer
|
33
|
-
#
|
34
|
-
# # Create an audit of changes made to @order during the <tt>:update</tt> or <tt>:process</tt> actions.
|
35
|
-
# track_changes :order, :only => [:update, :process]
|
36
|
-
def track_changes(*args)
|
37
|
-
options = args.extract_options!
|
38
|
-
models = args.flatten
|
39
|
-
options =
|
40
|
-
|
41
|
-
configuration = TrackChanges::Initializer.instance.configuration
|
42
|
-
|
43
|
-
audit_filter = AuditFilter.new(models,
|
44
|
-
:audit_accessor => configuration.audit_association,
|
45
|
-
:current_user => configuration.current_user,
|
46
|
-
:ignore_nil => configuration.ignore_nil)
|
47
|
-
around_filter(audit_filter, options)
|
48
|
-
end
|
49
|
-
|
50
|
-
# Uses a combination of <tt>before_filter</tt> and <tt>after_filter</tt>
|
51
|
-
# to act on changes made to a module during a controllers <tt>update</tt>
|
52
|
-
# action.
|
53
|
-
#
|
54
|
-
# Parameters:
|
55
|
-
#
|
56
|
-
# * <tt>model</tt>: A symbol of the model instance name to track changes to
|
57
|
-
# * <tt>only_if_changed</tt>: If true, will only yield block if changes is not empty. Defaults to <tt>true</tt>.
|
58
|
-
# * <tt>options</tt>: An options hash the will be supplied to <tt>before_filter</tt> and <tt>after_filter</tt>. Defaults to <tt>:only => :update</tt>.
|
59
|
-
# * <tt>&block</tt>: The supplied block is called with an instance of Result as its parameter.
|
60
|
-
def track_changes_to(models, only_if_changed = true, options = {:only => :update}, &block)
|
61
|
-
warn "[DEPRECATED] track_changes_to is deprecated. Use track_changes instead"
|
62
|
-
append_before_filter(options) do |controller|
|
63
|
-
track_filter = Filter.new(models, only_if_changed, block)
|
64
|
-
controller.track_changes_filter = track_filter
|
65
|
-
|
66
|
-
track_filter.before(controller)
|
67
|
-
end
|
68
|
-
|
69
|
-
append_after_filter(options)do |controller|
|
70
|
-
controller.track_changes_filter.after(controller)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
1
|
+
require 'active_support'
|
2
|
+
require 'track_changes/filter'
|
3
|
+
|
4
|
+
module TrackChanges
|
5
|
+
module ClassMethods
|
6
|
+
# Create an audit of the changes made to a module during a controller action.
|
7
|
+
# Some assumptions are made, primarily that the given models will have a
|
8
|
+
# polymorphic association to an Audit model. An example Audit model:
|
9
|
+
#
|
10
|
+
# class Audit < ActiveRecord::Base
|
11
|
+
# belongs_to :audited, :polymorphic => true
|
12
|
+
# belongs_to :user
|
13
|
+
# serialize :change_set
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# # Example model that would be audited:
|
17
|
+
# class Order < ActiveRecord::Base
|
18
|
+
# has_many :audits, :as => :audited
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# ==== Parameters
|
22
|
+
#
|
23
|
+
# * A symbol or many symbols of the name(s) of the instance variable to create audits for.
|
24
|
+
# * An optional hash that will be passed as filter conditions to <tt>around_filter</tt>
|
25
|
+
#
|
26
|
+
# ==== Examples
|
27
|
+
#
|
28
|
+
# # Create an audit of changes made to @order during the <tt>:update</tt> action.
|
29
|
+
# track_changes :order
|
30
|
+
#
|
31
|
+
# # Creates an audit of changes made to @order or @customer during the <tt>:update</tt> action.
|
32
|
+
# track_changes :order, :customer
|
33
|
+
#
|
34
|
+
# # Create an audit of changes made to @order during the <tt>:update</tt> or <tt>:process</tt> actions.
|
35
|
+
# track_changes :order, :only => [:update, :process]
|
36
|
+
def track_changes(*args)
|
37
|
+
options = args.extract_options!
|
38
|
+
models = args.flatten
|
39
|
+
options = {:only => :update} if options.empty?
|
40
|
+
|
41
|
+
configuration = TrackChanges::Initializer.instance.configuration
|
42
|
+
|
43
|
+
audit_filter = AuditFilter.new(models,
|
44
|
+
:audit_accessor => configuration.audit_association,
|
45
|
+
:current_user => configuration.current_user,
|
46
|
+
:ignore_nil => configuration.ignore_nil)
|
47
|
+
around_filter(audit_filter, options)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Uses a combination of <tt>before_filter</tt> and <tt>after_filter</tt>
|
51
|
+
# to act on changes made to a module during a controllers <tt>update</tt>
|
52
|
+
# action.
|
53
|
+
#
|
54
|
+
# Parameters:
|
55
|
+
#
|
56
|
+
# * <tt>model</tt>: A symbol of the model instance name to track changes to
|
57
|
+
# * <tt>only_if_changed</tt>: If true, will only yield block if changes is not empty. Defaults to <tt>true</tt>.
|
58
|
+
# * <tt>options</tt>: An options hash the will be supplied to <tt>before_filter</tt> and <tt>after_filter</tt>. Defaults to <tt>:only => :update</tt>.
|
59
|
+
# * <tt>&block</tt>: The supplied block is called with an instance of Result as its parameter.
|
60
|
+
def track_changes_to(models, only_if_changed = true, options = {:only => :update}, &block)
|
61
|
+
warn "[DEPRECATED] track_changes_to is deprecated. Use track_changes instead"
|
62
|
+
append_before_filter(options) do |controller|
|
63
|
+
track_filter = Filter.new(models, only_if_changed, block)
|
64
|
+
controller.track_changes_filter = track_filter
|
65
|
+
|
66
|
+
track_filter.before(controller)
|
67
|
+
end
|
68
|
+
|
69
|
+
append_after_filter(options)do |controller|
|
70
|
+
controller.track_changes_filter.after(controller)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -1,38 +1,38 @@
|
|
1
|
-
module TrackChanges
|
2
|
-
class Configuration
|
3
|
-
# The association used to create an audit. Defaults to
|
4
|
-
# <tt>:audits</tt>
|
5
|
-
#
|
6
|
-
# Example:
|
7
|
-
# :audits # => Call model.audits.create
|
8
|
-
# :changes # => Call model.changes.create
|
9
|
-
attr_accessor :audit_association
|
10
|
-
|
11
|
-
# The controller method called to obtain the current user.
|
12
|
-
# Defaults to <tt>:current_user</tt>
|
13
|
-
attr_accessor :current_user
|
14
|
-
|
15
|
-
# Ignore if the audited item is nil. Defaults to <tt>true</tt>.
|
16
|
-
attr_accessor :ignore_nil
|
17
|
-
|
18
|
-
def initialize
|
19
|
-
self.audit_association = default_audit_association
|
20
|
-
self.current_user = default_current_user
|
21
|
-
self.ignore_nil = default_ignore_nil
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def default_audit_association
|
27
|
-
:audits
|
28
|
-
end
|
29
|
-
|
30
|
-
def default_current_user
|
31
|
-
:current_user
|
32
|
-
end
|
33
|
-
|
34
|
-
def default_ignore_nil
|
35
|
-
true
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
1
|
+
module TrackChanges
|
2
|
+
class Configuration
|
3
|
+
# The association used to create an audit. Defaults to
|
4
|
+
# <tt>:audits</tt>
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
# :audits # => Call model.audits.create
|
8
|
+
# :changes # => Call model.changes.create
|
9
|
+
attr_accessor :audit_association
|
10
|
+
|
11
|
+
# The controller method called to obtain the current user.
|
12
|
+
# Defaults to <tt>:current_user</tt>
|
13
|
+
attr_accessor :current_user
|
14
|
+
|
15
|
+
# Ignore if the audited item is nil. Defaults to <tt>true</tt>.
|
16
|
+
attr_accessor :ignore_nil
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
self.audit_association = default_audit_association
|
20
|
+
self.current_user = default_current_user
|
21
|
+
self.ignore_nil = default_ignore_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def default_audit_association
|
27
|
+
:audits
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_current_user
|
31
|
+
:current_user
|
32
|
+
end
|
33
|
+
|
34
|
+
def default_ignore_nil
|
35
|
+
true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|