paper_trail 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
- 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:
488
+ You can turn PaperTrail on or off in three ways: globally, per request, or per class.
482
489
 
483
- >> Widget.paper_trail_off
490
+ ### Globally
484
491
 
485
- And on again like this:
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
- # Indicates whether or not PaperTrail is active for this class.
42
- # This is independent of whether PaperTrail is globally enabled or disabled.
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.paper_trail_active = false
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.paper_trail_active = true
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.paper_trail_active
169
+ PaperTrail.enabled? && PaperTrail.enabled_for_controller? && self.class.paper_trail_enabled_for_model
174
170
  end
175
171
  end
176
172
 
@@ -1,3 +1,3 @@
1
1
  module PaperTrail
2
- VERSION = '2.1.1'
2
+ VERSION = '2.2.0'
3
3
  end
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
@@ -20,4 +20,5 @@ Gem::Specification.new do |s|
20
20
  s.add_development_dependency 'shoulda', '2.10.3'
21
21
  s.add_development_dependency 'sqlite3-ruby', '~> 1.2'
22
22
  s.add_development_dependency 'capybara', '>= 0.4.0'
23
+ s.add_development_dependency 'turn'
23
24
  end
@@ -13,4 +13,5 @@ class ApplicationController < ActionController::Base
13
13
  def info_for_paper_trail
14
14
  {:ip => request.remote_ip, :user_agent => request.user_agent}
15
15
  end
16
+
16
17
  end
@@ -1,4 +1,9 @@
1
1
  class WidgetsController < ApplicationController
2
+
3
+ def paper_trail_enabled_for_controller
4
+ request.user_agent != 'Disable User-Agent'
5
+ end
6
+
2
7
  def create
3
8
  @widget = Widget.create params[:widget]
4
9
  head :ok
@@ -1,3 +1,4 @@
1
1
  class Animal < ActiveRecord::Base
2
2
  has_paper_trail
3
+ set_inheritance_column 'species'
3
4
  end
@@ -1,3 +1,2 @@
1
1
  class Cat < Animal
2
- set_inheritance_column 'species'
3
2
  end
@@ -1,3 +1,2 @@
1
1
  class Dog < Animal
2
- set_inheritance_column 'species'
3
2
  end
@@ -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 9, Version.count
22
- assert_equal 3, @animal.versions.count
23
- assert_equal 3, @dog.versions.count
24
- assert_equal 3, @cat.versions.count
25
-
26
- assert_equal 'Animal from the Muppets', @animal.versions.last.reify.name
27
- assert_equal 'Scooby', @dog.versions.last.reify.name
28
- assert_equal 'Garfield (I hate Mondays)', @cat.versions.last.reify.name
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
 
@@ -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: 9
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
- - 1
9
- - 1
10
- version: 2.1.1
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-03-31 00:00:00 +01:00
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
- requirement: &id001 !ruby/object:Gem::Requirement
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
- requirement: &id002 !ruby/object:Gem::Requirement
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
- requirement: &id003 !ruby/object:Gem::Requirement
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
- requirement: &id004 !ruby/object:Gem::Requirement
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: []