acts_as_audited 1.1.1 → 2.0.0
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/.gitignore +8 -2
- data/.yardopts +3 -0
- data/CHANGELOG +10 -2
- data/Gemfile +7 -0
- data/Gemfile.lock +108 -0
- data/LICENSE +2 -2
- data/README.textile +143 -0
- data/Rakefile +23 -42
- data/acts_as_audited.gemspec +13 -68
- data/autotest/discover.rb +1 -0
- data/lib/acts_as_audited/audit.rb +61 -40
- data/lib/acts_as_audited/audit_sweeper.rb +5 -27
- data/lib/acts_as_audited/auditor.rb +275 -0
- data/lib/acts_as_audited.rb +18 -212
- data/lib/generators/acts_as_audited/install_generator.rb +28 -0
- data/lib/generators/acts_as_audited/templates/add_association_to_audits.rb +11 -0
- data/lib/generators/acts_as_audited/templates/add_comment_to_audits.rb +9 -0
- data/lib/generators/acts_as_audited/templates/add_remote_address_to_audits.rb +10 -0
- data/{generators/audited_migration/templates/migration.rb → lib/generators/acts_as_audited/templates/install.rb} +9 -4
- data/lib/generators/acts_as_audited/templates/rename_association_to_associated.rb +23 -0
- data/lib/generators/acts_as_audited/templates/rename_changes_to_audited_changes.rb +9 -0
- data/lib/generators/acts_as_audited/templates/rename_parent_to_association.rb +11 -0
- data/lib/generators/acts_as_audited/upgrade_generator.rb +63 -0
- data/spec/acts_as_audited_spec.rb +473 -0
- data/spec/audit_spec.rb +190 -0
- data/spec/audit_sweeper_spec.rb +74 -0
- data/spec/audited_spec_helpers.rb +16 -0
- data/{test → spec}/db/schema.rb +21 -5
- data/spec/rails_app/config/application.rb +23 -0
- data/spec/rails_app/config/boot.rb +13 -0
- data/{test/db → spec/rails_app/config}/database.yml +10 -7
- data/spec/rails_app/config/environment.rb +5 -0
- data/spec/rails_app/config/environments/development.rb +19 -0
- data/spec/rails_app/config/environments/production.rb +33 -0
- data/spec/rails_app/config/environments/test.rb +33 -0
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_app/config/initializers/inflections.rb +2 -0
- data/spec/rails_app/config/initializers/secret_token.rb +2 -0
- data/spec/rails_app/config/routes.rb +6 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/spec_models.rb +88 -0
- data/test/db/version_1.rb +17 -0
- data/test/db/version_2.rb +18 -0
- data/test/db/version_3.rb +19 -0
- data/test/db/version_4.rb +20 -0
- data/test/db/version_5.rb +18 -0
- data/test/install_generator_test.rb +17 -0
- data/test/test_helper.rb +11 -67
- data/test/upgrade_generator_test.rb +65 -0
- metadata +106 -93
- data/README +0 -70
- data/VERSION +0 -1
- data/generators/audited_migration/USAGE +0 -7
- data/generators/audited_migration/audited_migration_generator.rb +0 -7
- data/init.rb +0 -1
- data/rails/init.rb +0 -8
- data/test/acts_as_audited_test.rb +0 -374
- data/test/audit_sweeper_test.rb +0 -31
- data/test/audit_test.rb +0 -179
data/.gitignore
CHANGED
data/.yardopts
ADDED
data/CHANGELOG
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
acts_as_audited ChangeLog
|
|
2
2
|
-------------------------------------------------------------------------------
|
|
3
|
+
|
|
4
|
+
* 2011-09-09 - Rails 3.x support
|
|
5
|
+
Support for associated audits
|
|
6
|
+
Support for remote IP address storage
|
|
7
|
+
Plenty of bug fixes and refactoring
|
|
8
|
+
[kennethkalmer, ineu, PatrickMa, jrozner, dwarburton, bsiggelkow, dgm]
|
|
3
9
|
* 2009-01-27 - Store old and new values for updates, and store all attributes on destroy.
|
|
4
10
|
Refactored revisioning methods to work as expected
|
|
5
11
|
* 2008-10-10 - changed to make it work in development mode
|
|
12
|
+
* 2008-09-24 - Add ability to record parent record of the record being audited
|
|
13
|
+
[Kenneth Kalmer]
|
|
6
14
|
* 2008-04-19 - refactored to make compatible with dirty tracking in edge rails
|
|
7
15
|
and to stop storing both old and new values in a single audit
|
|
8
16
|
* 2008-04-18 - Fix NoMethodError when trying to access the :previous revision
|
|
@@ -22,4 +30,4 @@
|
|
|
22
30
|
that saves the new value after every change and not just the
|
|
23
31
|
first, and performs proper type-casting before doing comparisons
|
|
24
32
|
* 2006-08-14 - The "changes" are now saved as a serialized hash
|
|
25
|
-
* 2006-07-21 - initial version
|
|
33
|
+
* 2006-07-21 - initial version
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: http://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
actionmailer (3.1.0)
|
|
5
|
+
actionpack (= 3.1.0)
|
|
6
|
+
mail (~> 2.3.0)
|
|
7
|
+
actionpack (3.1.0)
|
|
8
|
+
activemodel (= 3.1.0)
|
|
9
|
+
activesupport (= 3.1.0)
|
|
10
|
+
builder (~> 3.0.0)
|
|
11
|
+
erubis (~> 2.7.0)
|
|
12
|
+
i18n (~> 0.6)
|
|
13
|
+
rack (~> 1.3.2)
|
|
14
|
+
rack-cache (~> 1.0.3)
|
|
15
|
+
rack-mount (~> 0.8.2)
|
|
16
|
+
rack-test (~> 0.6.1)
|
|
17
|
+
sprockets (~> 2.0.0)
|
|
18
|
+
activemodel (3.1.0)
|
|
19
|
+
activesupport (= 3.1.0)
|
|
20
|
+
bcrypt-ruby (~> 3.0.0)
|
|
21
|
+
builder (~> 3.0.0)
|
|
22
|
+
i18n (~> 0.6)
|
|
23
|
+
activerecord (3.1.0)
|
|
24
|
+
activemodel (= 3.1.0)
|
|
25
|
+
activesupport (= 3.1.0)
|
|
26
|
+
arel (~> 2.2.1)
|
|
27
|
+
tzinfo (~> 0.3.29)
|
|
28
|
+
activeresource (3.1.0)
|
|
29
|
+
activemodel (= 3.1.0)
|
|
30
|
+
activesupport (= 3.1.0)
|
|
31
|
+
activesupport (3.1.0)
|
|
32
|
+
multi_json (~> 1.0)
|
|
33
|
+
arel (2.2.1)
|
|
34
|
+
bcrypt-ruby (3.0.0)
|
|
35
|
+
builder (3.0.0)
|
|
36
|
+
diff-lcs (1.1.3)
|
|
37
|
+
erubis (2.7.0)
|
|
38
|
+
hike (1.2.1)
|
|
39
|
+
i18n (0.6.0)
|
|
40
|
+
mail (2.3.0)
|
|
41
|
+
i18n (>= 0.4.0)
|
|
42
|
+
mime-types (~> 1.16)
|
|
43
|
+
treetop (~> 1.4.8)
|
|
44
|
+
mime-types (1.16)
|
|
45
|
+
multi_json (1.0.3)
|
|
46
|
+
polyglot (0.3.2)
|
|
47
|
+
rack (1.3.2)
|
|
48
|
+
rack-cache (1.0.3)
|
|
49
|
+
rack (>= 0.4)
|
|
50
|
+
rack-mount (0.8.3)
|
|
51
|
+
rack (>= 1.0.0)
|
|
52
|
+
rack-ssl (1.3.2)
|
|
53
|
+
rack
|
|
54
|
+
rack-test (0.6.1)
|
|
55
|
+
rack (>= 1.0)
|
|
56
|
+
rails (3.1.0)
|
|
57
|
+
actionmailer (= 3.1.0)
|
|
58
|
+
actionpack (= 3.1.0)
|
|
59
|
+
activerecord (= 3.1.0)
|
|
60
|
+
activeresource (= 3.1.0)
|
|
61
|
+
activesupport (= 3.1.0)
|
|
62
|
+
bundler (~> 1.0)
|
|
63
|
+
railties (= 3.1.0)
|
|
64
|
+
railties (3.1.0)
|
|
65
|
+
actionpack (= 3.1.0)
|
|
66
|
+
activesupport (= 3.1.0)
|
|
67
|
+
rack-ssl (~> 1.3.2)
|
|
68
|
+
rake (>= 0.8.7)
|
|
69
|
+
rdoc (~> 3.4)
|
|
70
|
+
thor (~> 0.14.6)
|
|
71
|
+
rake (0.9.2)
|
|
72
|
+
rcov (0.9.10)
|
|
73
|
+
rdoc (3.9.4)
|
|
74
|
+
rspec (2.4.0)
|
|
75
|
+
rspec-core (~> 2.4.0)
|
|
76
|
+
rspec-expectations (~> 2.4.0)
|
|
77
|
+
rspec-mocks (~> 2.4.0)
|
|
78
|
+
rspec-core (2.4.0)
|
|
79
|
+
rspec-expectations (2.4.0)
|
|
80
|
+
diff-lcs (~> 1.1.2)
|
|
81
|
+
rspec-mocks (2.4.0)
|
|
82
|
+
rspec-rails (2.4.1)
|
|
83
|
+
actionpack (~> 3.0)
|
|
84
|
+
activesupport (~> 3.0)
|
|
85
|
+
railties (~> 3.0)
|
|
86
|
+
rspec (~> 2.4.0)
|
|
87
|
+
sprockets (2.0.0)
|
|
88
|
+
hike (~> 1.2)
|
|
89
|
+
rack (~> 1.0)
|
|
90
|
+
tilt (!= 1.3.0, ~> 1.1)
|
|
91
|
+
sqlite3 (1.3.4)
|
|
92
|
+
thor (0.14.6)
|
|
93
|
+
tilt (1.3.3)
|
|
94
|
+
treetop (1.4.10)
|
|
95
|
+
polyglot
|
|
96
|
+
polyglot (>= 0.3.1)
|
|
97
|
+
tzinfo (0.3.29)
|
|
98
|
+
yard (0.7.2)
|
|
99
|
+
|
|
100
|
+
PLATFORMS
|
|
101
|
+
ruby
|
|
102
|
+
|
|
103
|
+
DEPENDENCIES
|
|
104
|
+
rails (>= 3.0.3)
|
|
105
|
+
rcov
|
|
106
|
+
rspec-rails (~> 2.4.0)
|
|
107
|
+
sqlite3
|
|
108
|
+
yard
|
data/LICENSE
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright ©
|
|
1
|
+
Copyright © 2010 Brandon Keepers - Collective Idea
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
4
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
16
16
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
17
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
18
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
-
THE SOFTWARE.
|
|
19
|
+
THE SOFTWARE.
|
data/README.textile
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
h1. acts_as_audited
|
|
2
|
+
|
|
3
|
+
+acts_as_audited+ is an ActiveRecord extension that logs all changes to your
|
|
4
|
+
models in an audits table, with optional revision comments. +acts_as_audited+
|
|
5
|
+
has been updated to work with Rails 3, to use it with older version of Rails,
|
|
6
|
+
please see the <tt>1.1-stable</tt> branch.
|
|
7
|
+
|
|
8
|
+
h2. Installation
|
|
9
|
+
|
|
10
|
+
In <tt>Gemfile</tt>:
|
|
11
|
+
|
|
12
|
+
@gem "acts_as_audited", "2.0.0"@
|
|
13
|
+
|
|
14
|
+
In your application root, run:
|
|
15
|
+
|
|
16
|
+
@$ bundle install@
|
|
17
|
+
|
|
18
|
+
Generate the migration:
|
|
19
|
+
|
|
20
|
+
* If installing without a previous version of +acts_as_audited+ or you do not mind overwriting your audits table:
|
|
21
|
+
|
|
22
|
+
@$ rails g acts_as_audited:install@
|
|
23
|
+
|
|
24
|
+
* If upgrading from a previous version of +acts_as_audited+ you might need some alterations to the audits table:
|
|
25
|
+
|
|
26
|
+
@$ rails g acts_as_audited:upgrade@
|
|
27
|
+
|
|
28
|
+
* After running one of the generators:
|
|
29
|
+
|
|
30
|
+
@$ rake db:migrate@
|
|
31
|
+
|
|
32
|
+
h2. Rails deprecation warning
|
|
33
|
+
|
|
34
|
+
Currently the gem causes the following deprecation warning to be emitted:
|
|
35
|
+
|
|
36
|
+
@DEPRECATION WARNING: reorder is deprecated. Please use except(:order).order(...) instead. (called from <class:Audit> at /Users/kenneth/Code/FOSS/acts_as_audited/lib/acts_as_audited/audit.rb:26)@
|
|
37
|
+
|
|
38
|
+
I'm well aware of the fact, and working towards a solution. The issue has also been brought up on the Rails lighthouse as "#6011":https://rails.lighthouseapp.com/projects/8994/tickets/6011-exceptorderorder-is-not-working-in-scopes. I'm keeping an eye on the issue and working towards another possible solution.
|
|
39
|
+
|
|
40
|
+
h2. Upgrading
|
|
41
|
+
|
|
42
|
+
Upgrading to Rails 3, or even between point releases of +acts_as_audited+, might require alterations to the audits table. After every upgrade please run the following generator:
|
|
43
|
+
|
|
44
|
+
@$ rails g acts_as_audited:upgrade@
|
|
45
|
+
|
|
46
|
+
The upgrade generator will only generate migrations that are missing, or no migrations at all if you are up to date.
|
|
47
|
+
|
|
48
|
+
h2. Usage
|
|
49
|
+
|
|
50
|
+
Declare +acts_as_audited+ on your models:
|
|
51
|
+
|
|
52
|
+
<pre><code>class User < ActiveRecord::Base
|
|
53
|
+
acts_as_audited :except => [:password, :mistress]
|
|
54
|
+
end
|
|
55
|
+
</code></pre>
|
|
56
|
+
|
|
57
|
+
Within a web request, will automatically record the user that made the change if your controller has a +current_user+ method. Comments can be added to an audit by setting <tt>model.audit_comments</tt>
|
|
58
|
+
before create/update/destroy. If the <tt>:comment_required</tt> option is given to +acts_as_audited+,
|
|
59
|
+
the save/update/destroy action will fail with add an error on <tt>model.audit_comment</tt> and triggering a
|
|
60
|
+
transaction rollback if <tt>model.audit_comment</tt> is nil.
|
|
61
|
+
|
|
62
|
+
To record an audit for an associated model, use the <tt>:associated_with</tt> option.
|
|
63
|
+
|
|
64
|
+
<pre><code>class User < ActiveRecord::Base
|
|
65
|
+
acts_as_audited :associated_with => :company
|
|
66
|
+
end
|
|
67
|
+
</code></pre>
|
|
68
|
+
|
|
69
|
+
If desired, the associated model can access its audits using <tt>has_associated_audits</tt>.
|
|
70
|
+
|
|
71
|
+
<pre><code>class Company < ActiveRecord::Base
|
|
72
|
+
has_many :users
|
|
73
|
+
has_associated_audits
|
|
74
|
+
end
|
|
75
|
+
</code></pre>
|
|
76
|
+
|
|
77
|
+
To record a user in the audits outside of a web request, you can use +as_user+:
|
|
78
|
+
|
|
79
|
+
<pre><code>Audit.as_user(user) do
|
|
80
|
+
# Perform changes on audited models
|
|
81
|
+
end
|
|
82
|
+
</code></pre>
|
|
83
|
+
|
|
84
|
+
h2. Caveats
|
|
85
|
+
|
|
86
|
+
If your model declares +attr_accessible+ after +acts_as_audited+, you need to set <tt>:protect</tt> to false. acts_as_audited uses +attr_protected+ internally to prevent malicious users from unassociating your audits, and Rails does not allow both +attr_protected+ and +attr_accessible+. It will default to false if +attr_accessible+ is called before +acts_as_audited+, but needs to be explicitly set if it is called after.
|
|
87
|
+
|
|
88
|
+
<pre><code>class User < ActiveRecord::Base
|
|
89
|
+
acts_as_audited :protect => false
|
|
90
|
+
attr_accessible :name
|
|
91
|
+
end
|
|
92
|
+
</code></pre>
|
|
93
|
+
|
|
94
|
+
Another caveat is documented in "issue 26":https://github.com/collectiveidea/acts_as_audited/issues#issue/26, where an audit created on the first request to the server does not have a user. Please review the Github issue for more details on how to fix this. It does not appear to affect Rails 3.
|
|
95
|
+
|
|
96
|
+
h2. Compatability
|
|
97
|
+
|
|
98
|
+
+acts_as_audited+ works with Rails 3.0.3 – 3.1.0. For older versions of Rails, please see the <tt>1.1-stable</tt> branch.
|
|
99
|
+
|
|
100
|
+
h2. Getting Help
|
|
101
|
+
|
|
102
|
+
Review the documentation at "http://rdoc.info/github/collectiveidea/acts_as_audited":http://rdoc.info/github/collectiveidea/acts_as_audited
|
|
103
|
+
|
|
104
|
+
Join "the mailing list":http://groups.google.com/group/acts_as_audited for getting help or offering suggestions.
|
|
105
|
+
|
|
106
|
+
h2. Branches
|
|
107
|
+
|
|
108
|
+
The <tt>master</tt> branch is considered stable, and you should be able to use it at any time.
|
|
109
|
+
|
|
110
|
+
h2. Contributing
|
|
111
|
+
|
|
112
|
+
In the spirit of "free software":http://www.fsf.org/licensing/essays/free-sw.html, **everyone** is encouraged to help improve this project.
|
|
113
|
+
|
|
114
|
+
Here are some ways *you* can contribute:
|
|
115
|
+
|
|
116
|
+
* using alpha, beta, and prerelease versions
|
|
117
|
+
* reporting bugs
|
|
118
|
+
* suggesting new features
|
|
119
|
+
* writing or editing documentation
|
|
120
|
+
* writing specifications
|
|
121
|
+
* writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace)
|
|
122
|
+
* refactoring code
|
|
123
|
+
* closing "issues":https://github.com/collectiveidea/acts_as_audited/issues
|
|
124
|
+
* reviewing patches
|
|
125
|
+
|
|
126
|
+
h2. Submitting an Issue
|
|
127
|
+
|
|
128
|
+
We use the "GitHub issue tracker":https://github.com/collectiveidea/acts_as_audited/issues to track bugs
|
|
129
|
+
and features. Before submitting a bug report or feature request, check to make sure it hasn't already
|
|
130
|
+
been submitted. You can indicate support for an existing issuse by voting it up. When submitting a
|
|
131
|
+
bug report, please include a "Gist":https://gist.github.com/ that includes a stack trace and any
|
|
132
|
+
details that may be necessary to reproduce the bug, including your gem version, Ruby version, and
|
|
133
|
+
operating system. Ideally, a bug report should include a pull request with failing specs.
|
|
134
|
+
|
|
135
|
+
h2. Submitting a Pull Request
|
|
136
|
+
|
|
137
|
+
1. Fork the project.
|
|
138
|
+
2. Create a topic branch.
|
|
139
|
+
3. Implement your feature or bug fix.
|
|
140
|
+
4. Add specs for your feature or bug fix.
|
|
141
|
+
5. Run @bundle exec rake@. If your changes are not 100% covered and passing, go back to step 4.
|
|
142
|
+
6. Commit and push your changes.
|
|
143
|
+
7. Submit a pull request. Please do not include changes to the gemspec, version, or history file. (If you want to create your own version for some reason, please do so in a separate commit.)
|
data/Rakefile
CHANGED
|
@@ -1,57 +1,38 @@
|
|
|
1
1
|
require 'rake'
|
|
2
|
-
require '
|
|
2
|
+
require 'rspec/core/rake_task'
|
|
3
3
|
require 'rake/testtask'
|
|
4
|
-
require '
|
|
4
|
+
require 'bundler'
|
|
5
|
+
Bundler::GemHelper.install_tasks
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
task :default => :test
|
|
7
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
gem.add_dependency 'activerecord', '>=2.1'
|
|
18
|
-
gem.add_development_dependency "thoughtbot-shoulda"
|
|
19
|
-
gem.add_development_dependency "jnunemaker-matchy"
|
|
20
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
|
21
|
-
end
|
|
22
|
-
# Jeweler::GemcutterTasks.new
|
|
23
|
-
rescue LoadError
|
|
24
|
-
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
|
9
|
+
require 'acts_as_audited'
|
|
10
|
+
|
|
11
|
+
desc 'Default: run specs and tests'
|
|
12
|
+
task :default => [:spec, :test]
|
|
13
|
+
|
|
14
|
+
RSpec::Core::RakeTask.new do |t|
|
|
15
|
+
t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
|
|
16
|
+
t.pattern = 'spec/*_spec.rb'
|
|
25
17
|
end
|
|
26
18
|
|
|
27
|
-
|
|
19
|
+
RSpec::Core::RakeTask.new(:rcov) do |t|
|
|
20
|
+
t.rcov = true
|
|
21
|
+
t.rcov_opts = %q[--exclude "spec"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc 'Test the acts_as_audited generators'
|
|
28
25
|
Rake::TestTask.new(:test) do |t|
|
|
29
26
|
t.libs << 'lib'
|
|
30
|
-
t.
|
|
27
|
+
t.libs << 'test'
|
|
28
|
+
t.pattern = 'test/*_test.rb'
|
|
31
29
|
t.verbose = true
|
|
32
30
|
end
|
|
33
31
|
|
|
34
|
-
task :test => :check_dependencies
|
|
35
|
-
|
|
36
32
|
begin
|
|
37
|
-
require '
|
|
38
|
-
|
|
39
|
-
test.libs << 'test'
|
|
40
|
-
test.pattern = 'test/**/*_test.rb'
|
|
41
|
-
test.verbose = true
|
|
42
|
-
test.rcov_opts = %w(--exclude test,/usr/lib/ruby,/Library/Ruby,$HOME/.gem --sort coverage)
|
|
43
|
-
end
|
|
33
|
+
require 'yard'
|
|
34
|
+
YARD::Rake::YardocTask.new
|
|
44
35
|
rescue LoadError
|
|
45
|
-
|
|
46
|
-
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
|
47
|
-
end
|
|
36
|
+
puts "YARD (or a dependency) not available. Install it with: bundle install"
|
|
48
37
|
end
|
|
49
38
|
|
|
50
|
-
desc 'Generate documentation for the acts_as_audited plugin.'
|
|
51
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
52
|
-
rdoc.rdoc_dir = 'doc'
|
|
53
|
-
rdoc.title = 'acts_as_audited'
|
|
54
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
|
55
|
-
rdoc.rdoc_files.include('README')
|
|
56
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
57
|
-
end
|
data/acts_as_audited.gemspec
CHANGED
|
@@ -1,73 +1,18 @@
|
|
|
1
|
-
# Generated by jeweler
|
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
|
4
1
|
# -*- encoding: utf-8 -*-
|
|
5
2
|
|
|
6
|
-
Gem::Specification.new do |
|
|
7
|
-
|
|
8
|
-
s.version = "1.1.1"
|
|
3
|
+
Gem::Specification.new do |gem|
|
|
4
|
+
gem.add_runtime_dependency(%q<rails>, [">= 3.0.3"])
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"LICENSE",
|
|
22
|
-
"README",
|
|
23
|
-
"Rakefile",
|
|
24
|
-
"VERSION",
|
|
25
|
-
"acts_as_audited.gemspec",
|
|
26
|
-
"generators/audited_migration/USAGE",
|
|
27
|
-
"generators/audited_migration/audited_migration_generator.rb",
|
|
28
|
-
"generators/audited_migration/templates/migration.rb",
|
|
29
|
-
"init.rb",
|
|
30
|
-
"lib/acts_as_audited.rb",
|
|
31
|
-
"lib/acts_as_audited/audit.rb",
|
|
32
|
-
"lib/acts_as_audited/audit_sweeper.rb",
|
|
33
|
-
"rails/init.rb",
|
|
34
|
-
"test/acts_as_audited_test.rb",
|
|
35
|
-
"test/audit_sweeper_test.rb",
|
|
36
|
-
"test/audit_test.rb",
|
|
37
|
-
"test/db/database.yml",
|
|
38
|
-
"test/db/schema.rb",
|
|
39
|
-
"test/test_helper.rb"
|
|
40
|
-
]
|
|
41
|
-
s.homepage = %q{http://github.com/collectiveidea/acts_as_audited}
|
|
42
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
|
43
|
-
s.require_paths = ["lib"]
|
|
44
|
-
s.rubygems_version = %q{1.3.6}
|
|
45
|
-
s.summary = %q{ActiveRecord extension that logs all changes to your models in an audits table}
|
|
46
|
-
s.test_files = [
|
|
47
|
-
"test/acts_as_audited_test.rb",
|
|
48
|
-
"test/audit_sweeper_test.rb",
|
|
49
|
-
"test/audit_test.rb",
|
|
50
|
-
"test/db/schema.rb",
|
|
51
|
-
"test/test_helper.rb"
|
|
52
|
-
]
|
|
53
|
-
|
|
54
|
-
if s.respond_to? :specification_version then
|
|
55
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
56
|
-
s.specification_version = 3
|
|
57
|
-
|
|
58
|
-
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
59
|
-
s.add_runtime_dependency(%q<activerecord>, [">= 2.1"])
|
|
60
|
-
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
|
61
|
-
s.add_development_dependency(%q<jnunemaker-matchy>, [">= 0"])
|
|
62
|
-
else
|
|
63
|
-
s.add_dependency(%q<activerecord>, [">= 2.1"])
|
|
64
|
-
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
|
65
|
-
s.add_dependency(%q<jnunemaker-matchy>, [">= 0"])
|
|
66
|
-
end
|
|
67
|
-
else
|
|
68
|
-
s.add_dependency(%q<activerecord>, [">= 2.1"])
|
|
69
|
-
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
|
70
|
-
s.add_dependency(%q<jnunemaker-matchy>, [">= 0"])
|
|
71
|
-
end
|
|
6
|
+
gem.authors = ["Brandon Keepers", "Kenneth Kalmer"]
|
|
7
|
+
gem.email = 'brandon@opensoul.org'
|
|
8
|
+
gem.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
|
|
9
|
+
gem.files = `git ls-files`.split("\n")
|
|
10
|
+
gem.homepage = %q{http://github.com/collectiveidea/acts_as_audited}
|
|
11
|
+
gem.rdoc_options = ["--main", "README.rdoc", "--line-numbers", "--inline-source"]
|
|
12
|
+
gem.require_paths = ["lib"]
|
|
13
|
+
gem.name = 'acts_as_audited'
|
|
14
|
+
gem.summary = %q{ActiveRecord extension that logs all changes to your models in an audits table}
|
|
15
|
+
gem.test_files = `git ls-files -- spec/* test/*`.split("\n")
|
|
16
|
+
gem.version = "2.0.0"
|
|
72
17
|
end
|
|
73
18
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
|
@@ -5,37 +5,75 @@ require 'set'
|
|
|
5
5
|
# * <tt>auditable</tt>: the ActiveRecord model that was changed
|
|
6
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
|
-
# * <tt>
|
|
8
|
+
# * <tt>audited_changes</tt>: a serialized hash of all the changes
|
|
9
|
+
# * <tt>comment</tt>: a comment set with the audit
|
|
9
10
|
# * <tt>created_at</tt>: Time that the change was performed
|
|
10
11
|
#
|
|
11
12
|
class Audit < ActiveRecord::Base
|
|
12
13
|
belongs_to :auditable, :polymorphic => true
|
|
13
14
|
belongs_to :user, :polymorphic => true
|
|
15
|
+
belongs_to :associated, :polymorphic => true
|
|
14
16
|
|
|
15
17
|
before_create :set_version_number, :set_audit_user
|
|
16
18
|
|
|
17
|
-
serialize :
|
|
19
|
+
serialize :audited_changes
|
|
18
20
|
|
|
19
21
|
cattr_accessor :audited_class_names
|
|
20
22
|
self.audited_class_names = Set.new
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
# Order by ver
|
|
25
|
+
default_scope order(:version)
|
|
26
|
+
scope :descending, reorder("version DESC")
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
|
|
30
|
+
# Returns the list of classes that are being audited
|
|
31
|
+
def audited_classes
|
|
32
|
+
audited_class_names.map(&:constantize)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# All audits made during the block called will be recorded as made
|
|
36
|
+
# by +user+. This method is hopefully threadsafe, making it ideal
|
|
37
|
+
# for background operations that require audit information.
|
|
38
|
+
def as_user(user, &block)
|
|
39
|
+
Thread.current[:acts_as_audited_user] = user
|
|
40
|
+
|
|
41
|
+
yieldval = yield
|
|
42
|
+
|
|
43
|
+
Thread.current[:acts_as_audited_user] = nil
|
|
44
|
+
|
|
45
|
+
yieldval
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @private
|
|
49
|
+
def reconstruct_attributes(audits)
|
|
50
|
+
attributes = {}
|
|
51
|
+
result = audits.collect do |audit|
|
|
52
|
+
attributes.merge!(audit.new_attributes).merge!(:version => audit.version)
|
|
53
|
+
yield attributes if block_given?
|
|
54
|
+
end
|
|
55
|
+
block_given? ? result : attributes
|
|
56
|
+
end
|
|
25
57
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Thread.current[:acts_as_audited_user] = user
|
|
58
|
+
# @private
|
|
59
|
+
def assign_revision_attributes(record, attributes)
|
|
60
|
+
attributes.each do |attr, val|
|
|
61
|
+
record = record.dup if record.frozen?
|
|
31
62
|
|
|
32
|
-
|
|
63
|
+
if record.respond_to?("#{attr}=")
|
|
64
|
+
record.attributes.has_key?(attr.to_s) ?
|
|
65
|
+
record[attr] = val :
|
|
66
|
+
record.send("#{attr}=", val)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
record
|
|
70
|
+
end
|
|
33
71
|
|
|
34
|
-
Thread.current[:acts_as_audited_user] = nil
|
|
35
72
|
end
|
|
36
73
|
|
|
37
74
|
# Allows user to be set to either a string or an ActiveRecord object
|
|
38
|
-
|
|
75
|
+
# @private
|
|
76
|
+
def user_as_string=(user)
|
|
39
77
|
# reset both either way
|
|
40
78
|
self.user_as_model = self.username = nil
|
|
41
79
|
user.is_a?(ActiveRecord::Base) ?
|
|
@@ -45,61 +83,44 @@ class Audit < ActiveRecord::Base
|
|
|
45
83
|
alias_method :user_as_model=, :user=
|
|
46
84
|
alias_method :user=, :user_as_string=
|
|
47
85
|
|
|
48
|
-
|
|
86
|
+
# @private
|
|
87
|
+
def user_as_string
|
|
49
88
|
self.user_as_model || self.username
|
|
50
89
|
end
|
|
51
90
|
alias_method :user_as_model, :user
|
|
52
91
|
alias_method :user, :user_as_string
|
|
53
92
|
|
|
93
|
+
# Return an instance of what the object looked like at this revision. If
|
|
94
|
+
# the object has been destroyed, this will be a new record.
|
|
54
95
|
def revision
|
|
55
96
|
clazz = auditable_type.constantize
|
|
56
|
-
|
|
97
|
+
( clazz.find_by_id(auditable_id) || clazz.new ).tap do |m|
|
|
57
98
|
Audit.assign_revision_attributes(m, self.class.reconstruct_attributes(ancestors).merge({:version => version}))
|
|
58
99
|
end
|
|
59
100
|
end
|
|
60
101
|
|
|
102
|
+
# Return all audits older than the current one.
|
|
61
103
|
def ancestors
|
|
62
|
-
self.class.
|
|
63
|
-
:conditions => ['auditable_id = ? and auditable_type = ? and version <= ?',
|
|
104
|
+
self.class.where(['auditable_id = ? and auditable_type = ? and version <= ?',
|
|
64
105
|
auditable_id, auditable_type, version])
|
|
65
106
|
end
|
|
66
107
|
|
|
67
108
|
# Returns a hash of the changed attributes with the new values
|
|
68
109
|
def new_attributes
|
|
69
|
-
(
|
|
70
|
-
attrs[attr] = Array
|
|
110
|
+
(audited_changes || {}).inject({}.with_indifferent_access) do |attrs,(attr,values)|
|
|
111
|
+
attrs[attr] = values.is_a?(Array) ? values.last : values
|
|
71
112
|
attrs
|
|
72
113
|
end
|
|
73
114
|
end
|
|
74
115
|
|
|
75
116
|
# Returns a hash of the changed attributes with the old values
|
|
76
117
|
def old_attributes
|
|
77
|
-
(
|
|
118
|
+
(audited_changes || {}).inject({}.with_indifferent_access) do |attrs,(attr,values)|
|
|
78
119
|
attrs[attr] = Array(values).first
|
|
79
120
|
attrs
|
|
80
121
|
end
|
|
81
122
|
end
|
|
82
123
|
|
|
83
|
-
def self.reconstruct_attributes(audits)
|
|
84
|
-
attributes = {}
|
|
85
|
-
result = audits.collect do |audit|
|
|
86
|
-
attributes.merge!(audit.new_attributes).merge!(:version => audit.version)
|
|
87
|
-
yield attributes if block_given?
|
|
88
|
-
end
|
|
89
|
-
block_given? ? result : attributes
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def self.assign_revision_attributes(record, attributes)
|
|
93
|
-
attributes.each do |attr, val|
|
|
94
|
-
if record.respond_to?("#{attr}=")
|
|
95
|
-
record.attributes.has_key?(attr.to_s) ?
|
|
96
|
-
record[attr] = val :
|
|
97
|
-
record.send("#{attr}=", val)
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
record
|
|
101
|
-
end
|
|
102
|
-
|
|
103
124
|
private
|
|
104
125
|
|
|
105
126
|
def set_version_number
|