auditing 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -2,11 +2,26 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  auditing (1.2.2)
5
+ activerecord (~> 3.0.0)
5
6
 
6
7
  GEM
7
8
  remote: http://rubygems.org/
8
9
  specs:
10
+ activemodel (3.0.5)
11
+ activesupport (= 3.0.5)
12
+ builder (~> 2.1.2)
13
+ i18n (~> 0.4)
14
+ activerecord (3.0.5)
15
+ activemodel (= 3.0.5)
16
+ activesupport (= 3.0.5)
17
+ arel (~> 2.0.2)
18
+ tzinfo (~> 0.3.23)
19
+ activesupport (3.0.5)
20
+ arel (2.0.9)
21
+ builder (2.1.2)
9
22
  diff-lcs (1.1.2)
23
+ i18n (0.5.0)
24
+ rake (0.8.7)
10
25
  rspec (2.4.0)
11
26
  rspec-core (~> 2.4.0)
12
27
  rspec-expectations (~> 2.4.0)
@@ -15,10 +30,16 @@ GEM
15
30
  rspec-expectations (2.4.0)
16
31
  diff-lcs (~> 1.1.2)
17
32
  rspec-mocks (2.4.0)
33
+ sqlite3 (1.3.3)
34
+ sqlite3-ruby (1.3.3)
35
+ sqlite3 (>= 1.3.3)
36
+ tzinfo (0.3.25)
18
37
 
19
38
  PLATFORMS
20
39
  ruby
21
40
 
22
41
  DEPENDENCIES
23
42
  auditing!
24
- rspec
43
+ rake (~> 0.8.7)
44
+ rspec (~> 2.4.0)
45
+ sqlite3-ruby
@@ -1,88 +1,84 @@
1
- = auditing
1
+ # auditing
2
2
 
3
3
  Auditing is a simple way to track and rollback changes to a record.
4
- == Sample Project
5
4
 
6
- http://github.com/bcantin/auditing_project
5
+ [![Build Status](http://travis-ci.org/bcantin/auditing.png)](http://travis-ci.org/bcantin/auditing)
6
+
7
+ ## Sample Project
8
+
9
+ https://github.com/bcantin/auditing_project
7
10
 
8
- == Installation
11
+ ## Installation
9
12
 
10
- gem install auditing
13
+ gem install auditing
14
+
15
+ There is a handy installer in the gem now. To see what it will do
11
16
 
12
- You will have to supply a model named Audit in your rails application
13
-
14
- rails g model audit
15
-
16
- Here is a migration for your audit model following migration
17
-
18
- create_table :audits, :force => true do |t|
19
- t.string :action
20
- t.string :auditable_type
21
- t.integer :auditable_id
22
- t.string :association_type
23
- t.integer :association_id
24
- t.string :field_name
25
- t.string :old_value
26
- t.string :new_value
27
- # t.integer :user_id
28
- t.boolean :undoable, :default => true
29
- t.timestamps
30
- end
17
+ rails g auditing:install --help
31
18
 
19
+ and, of course, to use it
20
+
21
+ rails g auditing:install
22
+ rake db:migrate
23
+
32
24
  If you want to track the user, uncomment the t.integer :user_id above. See the Tracking Users section below.
33
25
 
34
- Update your Audit class
35
26
 
36
- class Audit < ActiveRecord::Base
37
- include Auditing::Auditor
38
- belongs_to :auditable, :polymorphic => true
39
- belongs_to :association, :polymorphic => true
40
- end
41
-
42
-
43
- == Basic Usage
27
+ ## Upgrading to 1.3.0
28
+
29
+ New installs will not need to do this. Anyone that is using 1.2.2 and belong should
30
+
31
+ gem update auditing
32
+ # ... updates happen
33
+ rails g auditing:upgrade
34
+ rake db:migrate
35
+
36
+ This will create a new migration to update the :old_value and :new_value attribute from STRING to TEXT
37
+
38
+
39
+ ## Basic Usage
44
40
 
45
41
  To add auditing to all attributes on a model, simply add auditing to the model.
46
42
 
47
- class School < ActiveRecord::Base
48
- audit_enabled
49
- end
43
+ class School < ActiveRecord::Base
44
+ audit_enabled
45
+ end
50
46
 
51
47
  If you want more control over which attributes are audited, you can define them
52
48
  by supplying a fields hash
53
49
 
54
- class School < ActiveRecord::Base
55
- audit_enabled :fields => [:name, :established_on]
56
- end
50
+ class School < ActiveRecord::Base
51
+ audit_enabled :fields => [:name, :established_on]
52
+ end
57
53
 
58
54
  Auditing will not track "id", "created_at", or "updated_at" by default
59
55
 
60
- == belongs_to relationships
56
+ ## belongs_to relationships
61
57
 
62
58
  Auditing a belongs_to relationship works by keeping track of the foreign_id attribute. You do
63
59
  not need to add anything to the foreign model.
64
60
 
65
- == has_many relationships
61
+ ## has_many relationships
66
62
 
67
63
  You may have the need to keep track of a has_many relationship. To accomplish this, we have
68
64
  to enable a similar type of auditing on the other model(s)
69
65
 
70
- class Company < ActiveRecord::Base
71
- has_many :phone_numbers
72
- audit_enabled
73
- end
74
- class PhoneNumber < ActiveRecord::Base
75
- belongs_to :company
76
- audit_relationship_enabled
77
- end
66
+ class Company < ActiveRecord::Base
67
+ has_many :phone_numbers
68
+ audit_enabled
69
+ end
70
+ class PhoneNumber < ActiveRecord::Base
71
+ belongs_to :company
72
+ audit_relationship_enabled
73
+ end
78
74
 
79
75
  As above, you can supply a :fields hash of which attributes will be logged.
80
76
  If your relationship is polymorphic, you can supply an array of classes
81
77
  that you only want to log.
82
78
 
83
- audit_relationship_enabled :only => [Company, Person]
79
+ audit_relationship_enabled :only => [Company, Person]
84
80
 
85
- == Tracking Users
81
+ ## Tracking Users
86
82
 
87
83
  NOTE: there is probably a more elegant solution to this, if you know of
88
84
  one, please drop me a line.
@@ -94,68 +90,67 @@ To track which logged in users have made the changes, you will need to have a
94
90
  user_id column in your audits table. If you did not add it when you created
95
91
  the audits table, you can add it in another migration
96
92
 
97
- add_column :audits, :user_id, :integer
93
+ add_column :audits, :user_id, :integer
98
94
 
99
95
  You will need to add the relationship to the Audit class as well
100
96
 
101
- class Audit < ActiveRecord::Base
102
- belongs_to :user
103
- end
97
+ class Audit < ActiveRecord::Base
98
+ belongs_to :user
99
+ end
104
100
 
105
101
  If you want to see all the audits for a particular user, you can
106
102
  add the has_many relationship to the User model as well
107
-
108
- class User < ActiveRecord::Base
109
- has_many :audits
110
- end
103
+
104
+ class User < ActiveRecord::Base
105
+ has_many :audits
106
+ end
111
107
 
112
108
  Your user class should respond to a class method called current_user
113
109
  and current_user= (some authentication systems do this, others do not).
114
110
 
115
111
  Here is a suggested method
116
112
 
117
- class User < ActiveRecord::Base
118
-
119
- def self.current_user=(current_user)
120
- @current_user = current_user
121
- end
122
-
123
- def self.current_user
124
- @current_user
113
+ class User < ActiveRecord::Base
114
+
115
+ def self.current_user=(current_user)
116
+ @current_user = current_user
117
+ end
118
+
119
+ def self.current_user
120
+ @current_user
121
+ end
122
+
125
123
  end
126
-
127
- end
128
124
 
129
125
  Your ApplicationController should also set the current user so the auditing gem can
130
126
  get the current user properly
131
127
 
132
- class ApplicationController < ActionController::Base
128
+ class ApplicationController < ActionController::Base
129
+
130
+ before_filter :set_current_user
131
+ after_filter :unset_current_user
132
+
133
+ private
134
+
135
+ def set_current_user
136
+ User.current_user = current_user
137
+ end
138
+
139
+ def unset_current_user
140
+ User.current_user = nil
141
+ end
133
142
 
134
- before_filter :set_current_user
135
- after_filter :unset_current_user
136
-
137
- private
138
-
139
- def set_current_user
140
- User.current_user = current_user
141
- end
142
-
143
- def unset_current_user
144
- User.current_user = nil
145
143
  end
146
-
147
- end
148
144
 
149
- == Testing
145
+ ## Testing
150
146
 
151
147
  To run the tests, first clone this repo, then
152
148
 
153
- cd auditing
154
- bundle
155
- rspec spec
156
-
149
+ cd auditing
150
+ bundle
151
+ rake
157
152
 
158
- == Note on Patches/Pull Requests
153
+ ## Note on Patches/Pull Requests
159
154
 
160
155
  * Fork the project.
161
156
  * Make your feature addition or bug fix.
@@ -166,6 +161,6 @@ To run the tests, first clone this repo, then
166
161
  a commit by itself I can ignore when I pull)
167
162
  * Send me a pull request. Bonus points for topic branches.
168
163
 
169
- == Copyright
164
+ ## Copyright
170
165
 
171
- Copyright (c) 2010 Brad Cantin. See LICENSE for details.
166
+ Copyright (c) 2011 Brad Cantin. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,2 +1,34 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
1
+ # require 'bundler'
2
+ # Bundler::GemHelper.install_tasks
3
+
4
+ begin
5
+ require 'bundler/setup'
6
+ Bundler::GemHelper.install_tasks
7
+ rescue LoadError
8
+ puts 'although not required, bundler is recommened for running the tests'
9
+ end
10
+
11
+
12
+ task :default => [:test]
13
+
14
+ task :test do
15
+ sh "bundle exec rspec spec"
16
+ end
17
+
18
+
19
+ # require 'rake'
20
+
21
+ # begin
22
+ # require 'bundler/setup'
23
+ # Bundler::GemHelper.install_tasks
24
+ # rescue LoadError
25
+ # puts 'although not required, bundler is recommened for running the tests'
26
+ # end
27
+ #
28
+ # task :default => :spec
29
+ #
30
+ # require 'rspec/core/rake_task'
31
+ # RSpec::Core::RakeTask.new do |t|
32
+ # t.rspec_opts = ["--color", '--format doc']
33
+ # end
34
+ #
data/auditing.gemspec CHANGED
@@ -12,7 +12,11 @@ Gem::Specification.new do |s|
12
12
  s.description = %q{acts_as_versioned is good. This allows an attribute level rollback instead}
13
13
  s.summary = %q{A gem to keep track of audit hisory of a record}
14
14
 
15
- s.add_development_dependency "rspec"
15
+ s.add_development_dependency(%q<rspec>, ["~> 2.4.0"])
16
+ s.add_development_dependency(%q<rake>, ["~> 0.8.7"])
17
+ s.add_development_dependency "sqlite3-ruby"
18
+
19
+ s.add_dependency('activerecord', '~> 3.0.0')
16
20
 
17
21
  s.rubyforge_project = "auditing"
18
22
 
data/lib/auditing/base.rb CHANGED
@@ -68,9 +68,16 @@ module Auditing
68
68
  add_audit(:action => 'removed', :association => item, :undoable => false)
69
69
  end
70
70
 
71
+ def class_exists?(class_name)
72
+ klass = Module.const_get(class_name)
73
+ return klass.is_a?(Class)
74
+ rescue NameError
75
+ return false
76
+ end
77
+
71
78
  private
72
79
  def add_audit(hash={})
73
- if User.respond_to?(:current_user) && !User.current_user.blank?
80
+ if class_exists?('User') && User.respond_to?(:current_user) && !User.current_user.blank?
74
81
  hash[:user_id] = User.current_user.id
75
82
  end
76
83
  Audit.create!({:auditable => self}.merge(hash))
@@ -1,3 +1,3 @@
1
1
  module Auditing
2
- VERSION = "1.2.2"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -7,8 +7,8 @@ class CreateAudits < ActiveRecord::Migration
7
7
  t.string :association_type
8
8
  t.integer :association_id
9
9
  t.string :field_name
10
- t.string :old_value
11
- t.string :new_value
10
+ t.text :old_value
11
+ t.text :new_value
12
12
  # t.integer :user_id
13
13
  t.boolean :undoable, :default => true
14
14
  t.timestamps
@@ -0,0 +1,11 @@
1
+ class UpdateAudits < ActiveRecord::Migration
2
+ def self.up
3
+ change_column :audits, :old_value, :text
4
+ change_column :audits, :new_value, :text
5
+ end
6
+
7
+ def self.down
8
+ change_column :audits, :old_value, :string
9
+ change_column :audits, :new_value, :string
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ require 'rails/generators/migration'
2
+
3
+ module Auditing
4
+ module Generators
5
+ class UpgradeGenerator < Rails::Generators::Base
6
+
7
+ include Rails::Generators::Migration
8
+
9
+ source_root File.expand_path("../templates", __FILE__)
10
+
11
+ def create_migration
12
+ migration_template 'update_migration.rb', "db/migrate/update_audits.rb"
13
+ end
14
+
15
+ private
16
+
17
+ def self.next_migration_number(dirname) #:nodoc:
18
+ if ActiveRecord::Base.timestamped_migrations
19
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
20
+ else
21
+ "%.3d" % (current_migration_number(dirname) + 1)
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -204,4 +204,48 @@ describe "Base" do
204
204
  end
205
205
  end # belongs_to relationships
206
206
 
207
+ describe "text fields" do
208
+ before do
209
+ class Special < ActiveRecord::Base
210
+ audit_enabled
211
+ end
212
+ end
213
+
214
+ it "should properly work on creation" do
215
+ long_string = 'a'
216
+ 2000.times do
217
+ long_string << 'b'
218
+ end
219
+ special = Special.create(:text_field => long_string)
220
+ special.audits.should_not be_nil
221
+ end
222
+
223
+ describe "updating a text field" do
224
+ before do
225
+ @long_string = 'a'
226
+ @new_long_string = 'c'
227
+ 2000.times do
228
+ @long_string << 'b'
229
+ @new_long_string << 'd'
230
+ end
231
+ @special = Special.create(:text_field => @long_string)
232
+ end
233
+
234
+ it "should create an audit log when we update a text field" do
235
+ lambda {@special.update_attributes(:text_field => @new_long_string)
236
+ }.should change { Audit.count }.by(1)
237
+ end
238
+
239
+ it "should allow access to the old and new values" do
240
+ @special.update_attributes(:text_field => @new_long_string)
241
+ audit = @special.audits.first
242
+ audit.old_value.should eql(@long_string)
243
+ audit.new_value.should eql(@new_long_string)
244
+ end
245
+
246
+ end
247
+
248
+
249
+ end
250
+
207
251
  end
data/spec/schema.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  ActiveRecord::Schema.define(:version => 0) do
2
-
2
+
3
3
  create_table :audits do |t|
4
4
  t.string :action
5
5
  t.string :auditable_type
@@ -7,35 +7,35 @@ ActiveRecord::Schema.define(:version => 0) do
7
7
  t.string :association_type
8
8
  t.integer :association_id
9
9
  t.string :field_name
10
- t.string :old_value
11
- t.string :new_value
10
+ t.text :old_value
11
+ t.text :new_value
12
12
  t.integer :user_id
13
13
  t.boolean :undoable, :default => true
14
14
  t.timestamps
15
- end
16
-
15
+ end
16
+
17
17
  create_table :schools do |t|
18
18
  t.string :name
19
19
  t.datetime :established_on
20
20
  t.timestamps
21
21
  end
22
-
22
+
23
23
  create_table :cars do |t|
24
24
  t.string :name
25
25
  t.integer :auto_maker_id
26
26
  t.timestamps
27
27
  end
28
-
28
+
29
29
  create_table :auto_makers do |t|
30
30
  t.string :name
31
31
  t.timestamps
32
32
  end
33
-
33
+
34
34
  create_table :companies do |t|
35
35
  t.string :name
36
36
  t.timestamps
37
37
  end
38
-
38
+
39
39
  create_table :phone_numbers do |t|
40
40
  t.string :number
41
41
  t.string :extension
@@ -43,22 +43,26 @@ ActiveRecord::Schema.define(:version => 0) do
43
43
  t.integer :phoneable_id
44
44
  t.timestamps
45
45
  end
46
-
46
+
47
47
  create_table :people do |t|
48
48
  t.string :first_name
49
49
  t.string :last_name
50
50
  t.timestamps
51
51
  end
52
-
52
+
53
53
  create_table :employments do |t|
54
54
  t.integer :person_id
55
55
  t.integer :company_id
56
56
  t.string :start_date
57
57
  t.timestamps
58
58
  end
59
-
59
+
60
60
  create_table :users do |t|
61
61
  t.string :email
62
62
  end
63
63
 
64
- end
64
+ create_table :specials do |t|
65
+ t.text :text_field
66
+ end
67
+
68
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: auditing
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.2.2
5
+ version: 1.3.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Brad Cantin
@@ -10,20 +10,53 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-02-05 00:00:00 -05:00
13
+ date: 2011-04-14 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rspec
18
18
  prerelease: false
19
19
  requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: 2.4.0
25
+ type: :development
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 0.8.7
36
+ type: :development
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: sqlite3-ruby
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
20
42
  none: false
21
43
  requirements:
22
44
  - - ">="
23
45
  - !ruby/object:Gem::Version
24
46
  version: "0"
25
47
  type: :development
26
- version_requirements: *id001
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: activerecord
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ version: 3.0.0
58
+ type: :runtime
59
+ version_requirements: *id004
27
60
  description: acts_as_versioned is good. This allows an attribute level rollback instead
28
61
  email:
29
62
  - brad.cantin@gmail.com
@@ -42,7 +75,7 @@ files:
42
75
  - Gemfile
43
76
  - Gemfile.lock
44
77
  - LICENSE
45
- - README.rdoc
78
+ - README.markdown
46
79
  - Rakefile
47
80
  - auditing.gemspec
48
81
  - lib/auditing.rb
@@ -58,6 +91,8 @@ files:
58
91
  - lib/generators/auditing/templates/index.html.erb
59
92
  - lib/generators/auditing/templates/initializer.rb
60
93
  - lib/generators/auditing/templates/migration.rb
94
+ - lib/generators/auditing/templates/update_migration.rb
95
+ - lib/generators/auditing/upgrade_generator.rb
61
96
  - spec/auditing/audit_relationship_spec.rb
62
97
  - spec/auditing/auditor_spec.rb
63
98
  - spec/auditing/base_spec.rb