paper_trail 2.1.1 → 2.2.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/README.md +32 -7
- data/lib/paper_trail/controller.rb +8 -0
- data/lib/paper_trail/has_paper_trail.rb +5 -9
- data/lib/paper_trail/version_number.rb +1 -1
- data/lib/paper_trail.rb +9 -0
- data/paper_trail.gemspec +1 -0
- data/test/dummy/app/controllers/application_controller.rb +1 -0
- data/test/dummy/app/controllers/widgets_controller.rb +5 -0
- data/test/dummy/app/models/animal.rb +1 -0
- data/test/dummy/app/models/cat.rb +0 -1
- data/test/dummy/app/models/dog.rb +0 -1
- data/test/functional/controller_test.rb +30 -0
- data/test/test_helper.rb +6 -0
- data/test/unit/inheritance_column_test.rb +19 -8
- data/test/unit/model_test.rb +9 -9
- metadata +31 -17
data/README.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
# Extended
|
2
|
+
|
3
|
+
Added the possibility to disable/enable PaperTrail from a controller.
|
4
|
+
|
5
|
+
|
6
|
+
|
1
7
|
# PaperTrail
|
2
8
|
|
3
9
|
PaperTrail lets you track changes to your models' data. It's good for auditing or versioning. You can see how a model looked at any stage in its lifecycle, revert it to any version, and even undelete it after it's been destroyed.
|
@@ -18,6 +24,7 @@ There's an excellent [Railscast on implementing Undo with Paper Trail](http://ra
|
|
18
24
|
* Allows you to store arbitrary model-level metadata with each version (useful for filtering versions).
|
19
25
|
* Allows you to store arbitrary controller-level information with each version, e.g. remote IP.
|
20
26
|
* Can be turned off/on per class (useful for migrations).
|
27
|
+
* Can be turned off/on per request (useful for testing with an external service).
|
21
28
|
* Can be turned off/on globally (useful for testing).
|
22
29
|
* No configuration necessary.
|
23
30
|
* Stores everything in a single database table by default (generates migration for you), or can use separate tables for separate models.
|
@@ -478,15 +485,11 @@ For diffing two ActiveRecord objects:
|
|
478
485
|
|
479
486
|
Sometimes you don't want to store changes. Perhaps you are only interested in changes made by your users and don't need to store changes you make yourself in, say, a migration -- or when testing your application.
|
480
487
|
|
481
|
-
|
488
|
+
You can turn PaperTrail on or off in three ways: globally, per request, or per class.
|
482
489
|
|
483
|
-
|
490
|
+
### Globally
|
484
491
|
|
485
|
-
|
486
|
-
|
487
|
-
>> Widget.paper_trail_on
|
488
|
-
|
489
|
-
You can also disable PaperTrail for all models:
|
492
|
+
On a global level you can turn PaperTrail off like this:
|
490
493
|
|
491
494
|
>> PaperTrail.enabled = false
|
492
495
|
|
@@ -518,6 +521,27 @@ And then use it in your tests like this:
|
|
518
521
|
end
|
519
522
|
end
|
520
523
|
|
524
|
+
### Per request
|
525
|
+
|
526
|
+
You can turn PaperTrail on or off per request by adding a `paper_trail_enabled_for_controller` method to your controller which returns true or false:
|
527
|
+
|
528
|
+
class ApplicationController < ActionController::Base
|
529
|
+
def paper_trail_enabled_for_controller
|
530
|
+
request.user_agent != 'Disable User-Agent'
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
### Per class
|
535
|
+
|
536
|
+
If you are about change some widgets and you don't want a paper trail of your changes, you can turn PaperTrail off like this:
|
537
|
+
|
538
|
+
>> Widget.paper_trail_off
|
539
|
+
|
540
|
+
And on again like this:
|
541
|
+
|
542
|
+
>> Widget.paper_trail_on
|
543
|
+
|
544
|
+
|
521
545
|
|
522
546
|
## Deleting Old Versions
|
523
547
|
|
@@ -583,6 +607,7 @@ Many thanks to:
|
|
583
607
|
* [Matthew MacLeod](https://github.com/mattmacleod)
|
584
608
|
* [benzittlau](https://github.com/benzittlau)
|
585
609
|
* [Tom Derks](https://github.com/EgoH)
|
610
|
+
* [Jonas Hoglund](https://github.com/jhoglund)
|
586
611
|
|
587
612
|
|
588
613
|
## Inspirations
|
@@ -4,6 +4,7 @@ module PaperTrail
|
|
4
4
|
def self.included(base)
|
5
5
|
base.before_filter :set_paper_trail_whodunnit
|
6
6
|
base.before_filter :set_paper_trail_controller_info
|
7
|
+
base.before_filter :set_paper_trail_enabled_for_controller
|
7
8
|
end
|
8
9
|
|
9
10
|
protected
|
@@ -40,6 +41,13 @@ module PaperTrail
|
|
40
41
|
|
41
42
|
private
|
42
43
|
|
44
|
+
# Tells PaperTrail if version should be saved.
|
45
|
+
def set_paper_trail_enabled_for_controller
|
46
|
+
if respond_to? :paper_trail_enabled_for_controller
|
47
|
+
::PaperTrail.enabled_for_controller = paper_trail_enabled_for_controller
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
43
51
|
# Tells PaperTrail who is responsible for any changes that occur.
|
44
52
|
def set_paper_trail_whodunnit
|
45
53
|
::PaperTrail.whodunnit = user_for_paper_trail
|
@@ -38,10 +38,8 @@ module PaperTrail
|
|
38
38
|
cattr_accessor :meta
|
39
39
|
self.meta = options[:meta] || {}
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
cattr_accessor :paper_trail_active
|
44
|
-
self.paper_trail_active = true
|
41
|
+
cattr_accessor :paper_trail_enabled_for_model
|
42
|
+
self.paper_trail_enabled_for_model = true
|
45
43
|
|
46
44
|
has_many :versions, :class_name => version_class_name, :as => :item, :order => 'created_at ASC, id ASC'
|
47
45
|
|
@@ -52,12 +50,12 @@ module PaperTrail
|
|
52
50
|
|
53
51
|
# Switches PaperTrail off for this class.
|
54
52
|
def paper_trail_off
|
55
|
-
self.
|
53
|
+
self.paper_trail_enabled_for_model = false
|
56
54
|
end
|
57
55
|
|
58
56
|
# Switches PaperTrail on for this class.
|
59
57
|
def paper_trail_on
|
60
|
-
self.
|
58
|
+
self.paper_trail_enabled_for_model = true
|
61
59
|
end
|
62
60
|
end
|
63
61
|
|
@@ -167,10 +165,8 @@ module PaperTrail
|
|
167
165
|
changed - self.class.ignore
|
168
166
|
end
|
169
167
|
|
170
|
-
# Returns `true` if PaperTrail is globally enabled and active for this class,
|
171
|
-
# `false` otherwise.
|
172
168
|
def switched_on?
|
173
|
-
PaperTrail.enabled? && self.class.
|
169
|
+
PaperTrail.enabled? && PaperTrail.enabled_for_controller? && self.class.paper_trail_enabled_for_model
|
174
170
|
end
|
175
171
|
end
|
176
172
|
|
data/lib/paper_trail.rb
CHANGED
@@ -20,6 +20,15 @@ module PaperTrail
|
|
20
20
|
!!PaperTrail.config.enabled
|
21
21
|
end
|
22
22
|
|
23
|
+
# Returns `true` if PaperTrail is enabled for the controller, `false` otherwise.
|
24
|
+
def self.enabled_for_controller?
|
25
|
+
!!paper_trail_store[:request_enabled_for_controller]
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sets if PaperTrails is disabled by controller
|
29
|
+
def self.enabled_for_controller=(value)
|
30
|
+
paper_trail_store[:request_enabled_for_controller] = value
|
31
|
+
end
|
23
32
|
|
24
33
|
# Returns who is reponsible for any changes that occur.
|
25
34
|
def self.whodunnit
|
data/paper_trail.gemspec
CHANGED
@@ -7,6 +7,36 @@ class ControllerTest < ActionController::TestCase
|
|
7
7
|
@request.env['REMOTE_ADDR'] = '127.0.0.1'
|
8
8
|
end
|
9
9
|
|
10
|
+
teardown do
|
11
|
+
PaperTrail.enabled_for_controller = true
|
12
|
+
end
|
13
|
+
|
14
|
+
test 'disable on create' do
|
15
|
+
@request.env['HTTP_USER_AGENT'] = 'Disable User-Agent'
|
16
|
+
post :create, :widget => { :name => 'Flugel' }
|
17
|
+
assert_equal 0, assigns(:widget).versions.length
|
18
|
+
end
|
19
|
+
|
20
|
+
test 'disable on update' do
|
21
|
+
@request.env['HTTP_USER_AGENT'] = 'Disable User-Agent'
|
22
|
+
post :create, :widget => { :name => 'Flugel' }
|
23
|
+
w = assigns(:widget)
|
24
|
+
assert_equal 0, w.versions.length
|
25
|
+
put :update, :id => w.id, :widget => { :name => 'Bugle' }
|
26
|
+
widget = assigns(:widget)
|
27
|
+
assert_equal 0, widget.versions.length
|
28
|
+
end
|
29
|
+
|
30
|
+
test 'disable on destroy' do
|
31
|
+
@request.env['HTTP_USER_AGENT'] = 'Disable User-Agent'
|
32
|
+
post :create, :widget => { :name => 'Flugel' }
|
33
|
+
w = assigns(:widget)
|
34
|
+
assert_equal 0, w.versions.length
|
35
|
+
delete :destroy, :id => w.id
|
36
|
+
widget = assigns(:widget)
|
37
|
+
assert_equal 0, Version.with_item_keys('Widget', w.id).size
|
38
|
+
end
|
39
|
+
|
10
40
|
test 'create' do
|
11
41
|
post :create, :widget => { :name => 'Flugel' }
|
12
42
|
widget = assigns(:widget)
|
data/test/test_helper.rb
CHANGED
@@ -4,6 +4,12 @@ ENV["RAILS_ENV"] = "test"
|
|
4
4
|
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
5
5
|
require "rails/test_help"
|
6
6
|
|
7
|
+
begin
|
8
|
+
require 'turn'
|
9
|
+
rescue LoadError
|
10
|
+
# noop
|
11
|
+
end
|
12
|
+
|
7
13
|
#ActionMailer::Base.delivery_method = :test
|
8
14
|
#ActionMailer::Base.perform_deliveries = true
|
9
15
|
#ActionMailer::Base.default_url_options[:host] = "test.com"
|
@@ -7,25 +7,36 @@ class InheritanceColumnTest < ActiveSupport::TestCase
|
|
7
7
|
@animal = Animal.create :name => 'Animal'
|
8
8
|
@animal.update_attributes :name => 'Animal from the Muppets'
|
9
9
|
@animal.update_attributes :name => 'Animal Muppet'
|
10
|
+
@animal.destroy
|
10
11
|
|
11
12
|
@dog = Dog.create :name => 'Snoopy'
|
12
13
|
@dog.update_attributes :name => 'Scooby'
|
13
14
|
@dog.update_attributes :name => 'Scooby Doo'
|
15
|
+
@dog.destroy
|
14
16
|
|
15
17
|
@cat = Cat.create :name => 'Garfield'
|
16
18
|
@cat.update_attributes :name => 'Garfield (I hate Mondays)'
|
17
19
|
@cat.update_attributes :name => 'Garfield The Cat'
|
20
|
+
@cat.destroy
|
18
21
|
end
|
19
22
|
|
20
23
|
should 'work with custom STI inheritance column' do
|
21
|
-
assert_equal
|
22
|
-
assert_equal
|
23
|
-
|
24
|
-
assert_equal
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
assert_equal 12, Version.count
|
25
|
+
assert_equal 4, @animal.versions.count
|
26
|
+
assert @animal.versions.first.reify.nil?
|
27
|
+
@animal.versions[1..-1].each { |v| assert_equal 'Animal', v.reify.class.name }
|
28
|
+
|
29
|
+
# For some reason `@dog.versions` doesn't include the final `destroy` version.
|
30
|
+
# Neither do `@dog.versions.scoped` nor `@dog.versions(true)` nor `@dog.versions.reload`.
|
31
|
+
dog_versions = Version.where(:item_id => @dog.id)
|
32
|
+
assert_equal 4, dog_versions.count
|
33
|
+
assert dog_versions.first.reify.nil?
|
34
|
+
dog_versions[1..-1].each { |v| assert_equal 'Dog', v.reify.class.name }
|
35
|
+
|
36
|
+
cat_versions = Version.where(:item_id => @cat.id)
|
37
|
+
assert_equal 4, cat_versions.count
|
38
|
+
assert cat_versions.first.reify.nil?
|
39
|
+
cat_versions[1..-1].each { |v| assert_equal 'Cat', v.reify.class.name }
|
29
40
|
end
|
30
41
|
end
|
31
42
|
|
data/test/unit/model_test.rb
CHANGED
@@ -14,7 +14,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
14
14
|
setup { @article.update_attributes :title => 'My first title', :content => 'Some text here.' }
|
15
15
|
should_change('the number of versions', :by => 1) { Version.count }
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
context 'which updates a selected column' do
|
19
19
|
setup { @article.update_attributes :content => 'Some text here.' }
|
20
20
|
should_change('the number of versions', :by => 1) { Version.count }
|
@@ -24,7 +24,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
24
24
|
setup { @article.update_attributes :abstract => 'Other abstract'}
|
25
25
|
should_not_change('the number of versions') { Version.count }
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
end
|
29
29
|
|
30
30
|
|
@@ -712,36 +712,36 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
712
712
|
|
713
713
|
context 'A new model instance which uses a custom Version class' do
|
714
714
|
setup { @post = Post.new }
|
715
|
-
|
715
|
+
|
716
716
|
context 'which is then saved' do
|
717
717
|
setup { @post.save }
|
718
718
|
should_change('the number of post versions') { PostVersion.count }
|
719
719
|
should_not_change('the number of versions') { Version.count }
|
720
720
|
end
|
721
721
|
end
|
722
|
-
|
722
|
+
|
723
723
|
context 'An existing model instance which uses a custom Version class' do
|
724
724
|
setup { @post = Post.create }
|
725
|
-
|
725
|
+
|
726
726
|
context 'on the first version' do
|
727
727
|
setup { @version = @post.versions.first }
|
728
|
-
|
728
|
+
|
729
729
|
should 'have the correct index' do
|
730
730
|
assert_equal 0, @version.index
|
731
731
|
end
|
732
732
|
end
|
733
|
-
|
733
|
+
|
734
734
|
should 'should have versions of the custom class' do
|
735
735
|
assert_equal "PostVersion", @post.versions.first.class.name
|
736
736
|
end
|
737
|
-
|
737
|
+
|
738
738
|
context 'which is modified' do
|
739
739
|
setup { @post.update_attributes({ :content => "Some new content" }) }
|
740
740
|
should_change('the number of post versions') { PostVersion.count }
|
741
741
|
should_not_change('the number of versions') { Version.count }
|
742
742
|
end
|
743
743
|
end
|
744
|
-
|
744
|
+
|
745
745
|
|
746
746
|
context 'An overwritten default accessor' do
|
747
747
|
setup do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paper_trail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 2.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 2.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andy Stewart
|
@@ -15,13 +15,12 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-04-05 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
-
name: rails
|
23
22
|
prerelease: false
|
24
|
-
|
23
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
25
|
requirements:
|
27
26
|
- - ~>
|
@@ -30,12 +29,12 @@ dependencies:
|
|
30
29
|
segments:
|
31
30
|
- 3
|
32
31
|
version: "3"
|
32
|
+
requirement: *id001
|
33
|
+
name: rails
|
33
34
|
type: :runtime
|
34
|
-
version_requirements: *id001
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
|
-
name: shoulda
|
37
36
|
prerelease: false
|
38
|
-
|
37
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
38
|
none: false
|
40
39
|
requirements:
|
41
40
|
- - "="
|
@@ -46,12 +45,12 @@ dependencies:
|
|
46
45
|
- 10
|
47
46
|
- 3
|
48
47
|
version: 2.10.3
|
48
|
+
requirement: *id002
|
49
|
+
name: shoulda
|
49
50
|
type: :development
|
50
|
-
version_requirements: *id002
|
51
51
|
- !ruby/object:Gem::Dependency
|
52
|
-
name: sqlite3-ruby
|
53
52
|
prerelease: false
|
54
|
-
|
53
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
55
54
|
none: false
|
56
55
|
requirements:
|
57
56
|
- - ~>
|
@@ -61,12 +60,12 @@ dependencies:
|
|
61
60
|
- 1
|
62
61
|
- 2
|
63
62
|
version: "1.2"
|
63
|
+
requirement: *id003
|
64
|
+
name: sqlite3-ruby
|
64
65
|
type: :development
|
65
|
-
version_requirements: *id003
|
66
66
|
- !ruby/object:Gem::Dependency
|
67
|
-
name: capybara
|
68
67
|
prerelease: false
|
69
|
-
|
68
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
70
69
|
none: false
|
71
70
|
requirements:
|
72
71
|
- - ">="
|
@@ -77,8 +76,23 @@ dependencies:
|
|
77
76
|
- 4
|
78
77
|
- 0
|
79
78
|
version: 0.4.0
|
79
|
+
requirement: *id004
|
80
|
+
name: capybara
|
81
|
+
type: :development
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 3
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
version: "0"
|
93
|
+
requirement: *id005
|
94
|
+
name: turn
|
80
95
|
type: :development
|
81
|
-
version_requirements: *id004
|
82
96
|
description: Track changes to your models' data. Good for auditing or versioning.
|
83
97
|
email: boss@airbladesoftware.com
|
84
98
|
executables: []
|