paper_trail 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/CHANGELOG.md +23 -3
- data/README.md +49 -22
- data/gemfiles/3.0.gemfile +1 -0
- data/lib/generators/paper_trail/install_generator.rb +1 -2
- data/lib/generators/paper_trail/templates/add_object_changes_to_versions.rb +5 -0
- data/lib/generators/paper_trail/templates/create_versions.rb +1 -6
- data/lib/paper_trail.rb +11 -1
- data/lib/paper_trail/frameworks/rails.rb +2 -2
- data/lib/paper_trail/frameworks/rspec.rb +3 -2
- data/lib/paper_trail/frameworks/rspec/helpers.rb +25 -0
- data/lib/paper_trail/frameworks/sinatra.rb +1 -1
- data/lib/paper_trail/has_paper_trail.rb +55 -14
- data/lib/paper_trail/version_number.rb +1 -1
- data/paper_trail.gemspec +1 -0
- data/spec/generators/install_generator_spec.rb +67 -0
- data/spec/models/widget_spec.rb +120 -2
- data/spec/paper_trail_spec.rb +22 -1
- data/spec/requests/articles_spec.rb +5 -9
- data/spec/spec_helper.rb +1 -1
- data/test/dummy/app/controllers/application_controller.rb +4 -1
- data/test/dummy/app/controllers/test_controller.rb +1 -1
- data/test/dummy/app/models/elephant.rb +1 -1
- data/test/dummy/app/models/widget.rb +1 -1
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +2 -2
- data/test/dummy/db/schema.rb +1 -0
- data/test/functional/modular_sinatra_test.rb +4 -1
- data/test/functional/sinatra_test.rb +4 -1
- data/test/functional/thread_safety_test.rb +23 -1
- data/test/unit/model_test.rb +25 -12
- data/test/unit/protected_attrs_test.rb +2 -2
- metadata +21 -5
- data/lib/generators/paper_trail/templates/add_object_changes_column_to_versions.rb +0 -9
- data/lib/paper_trail/frameworks/rspec/extensions.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1054af34e2822ac77b034943d283274d8a9daa62
|
4
|
+
data.tar.gz: 219b4b1fd749df6babf4517ff056ae223ba6bb6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0397014880df4049900f6191b41d31c70b4bee0373943dfd1fd8cc876ed4ed220273a5e973c8d8bae471be9ebc875d12b23ede208bf246ebe2247a230fc99f03
|
7
|
+
data.tar.gz: 9697bea9302726a452c319909a77face2e281392ca29a187f1bd7d5c3f35ce92b1ba94e3c9698aca50b5c88623d0bcb0b7f66fc692a2fe723a7ef171efece060
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
## 3.0.1
|
2
|
+
|
3
|
+
- [#340](https://github.com/airblade/paper_trail/issues/340) - Prevent potential error encountered when using the `InstallGenerator`
|
4
|
+
with Rails `4.1.0.rc1`.
|
5
|
+
- [#334](https://github.com/airblade/paper_trail/pull/334) - Add small-scope `whodunnit` method to `PaperTrail::Model::InstanceMethods`.
|
6
|
+
- [#329](https://github.com/airblade/paper_trail/issues/329) - Add `touch_with_version` method to `PaperTrail::Model::InstanceMethods`,
|
7
|
+
to allow for generating a version `touch`ing a model.
|
8
|
+
- [#328](https://github.com/airblade/paper_trail/pull/328) / [#326](https://github.com/airblade/paper_trail/issues/326) /
|
9
|
+
[#307](https://github.com/airblade/paper_trail/issues/307) - `Model.paper_trail_enabled_for_model?` and
|
10
|
+
`model_instance.without_versioning` is now thread-safe.
|
11
|
+
- [#316](https://github.com/airblade/paper_trail/issues/316) - `user_for_paper_trail` should default to `current_user.try(:id)`
|
12
|
+
instead of `current_user` (if `current_user` is defined).
|
13
|
+
- [#313](https://github.com/airblade/paper_trail/pull/313) - Make the `Rails::Controller` helper compatible with
|
14
|
+
`ActionController::API` for compatibility with the [`rails-api`](https://github.com/rails-api/rails-api) gem.
|
15
|
+
- [#312](https://github.com/airblade/paper_trail/issues/312) - Fix RSpec `with_versioning` class level helper method.
|
16
|
+
- `model_instance.without_versioning` now yields the `model_instance`, enabling syntax like this:
|
17
|
+
`model_instance.without_versioning { |obj| obj.update_attributes(:name => 'value') }`.
|
18
|
+
- Deprecated `Model.paper_trail_on` and `Model.paper_trail_off` in favor of bang versions of the methods. Deprecation warning
|
19
|
+
informs users that the non-bang versions of the methods will be removed in version `3.1.0`.
|
20
|
+
|
1
21
|
## 3.0.0
|
2
22
|
|
3
23
|
- [#305](https://github.com/airblade/paper_trail/pull/305) - `PaperTrail::VERSION` should be loaded at runtime.
|
@@ -35,11 +55,11 @@
|
|
35
55
|
## 2.7.2
|
36
56
|
|
37
57
|
- [#228](https://github.com/airblade/paper_trail/issues/228) - Refactored default `user_for_paper_trail` method implementation
|
38
|
-
|
58
|
+
so that `current_user` only gets invoked if it is defined.
|
39
59
|
- [#219](https://github.com/airblade/paper_trail/pull/219) - Fixed issue where attributes stored with `nil` value might not get
|
40
|
-
|
60
|
+
reified properly depending on the way the serializer worked.
|
41
61
|
- [#213](https://github.com/airblade/paper_trail/issues/213) - Added a `version_limit` option to the `PaperTrail::Config` options
|
42
|
-
|
62
|
+
that can be used to restrict the number of versions PaperTrail will store per object instance.
|
43
63
|
- [#187](https://github.com/airblade/paper_trail/pull/187) - Confirmed JRuby support.
|
44
64
|
- [#174](https://github.com/airblade/paper_trail/pull/174) - The `event` field on the versions table can now be customized.
|
45
65
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# PaperTrail [![Build Status](https://
|
1
|
+
# PaperTrail [![Build Status](https://img.shields.io/travis/airblade/paper_trail/master.svg)](https://travis-ci.org/airblade/paper_trail) [![Dependency Status](https://img.shields.io/gemnasium/airblade/paper_trail.svg)](https://gemnasium.com/airblade/paper_trail)
|
2
2
|
|
3
3
|
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.
|
4
4
|
|
@@ -42,7 +42,7 @@ The Rails 2.3 code is on the [`rails2`](https://github.com/airblade/paper_trail/
|
|
42
42
|
|
43
43
|
1. Add `PaperTrail` to your `Gemfile`.
|
44
44
|
|
45
|
-
`gem 'paper_trail', '~> 3.0.
|
45
|
+
`gem 'paper_trail', '~> 3.0.1'`
|
46
46
|
|
47
47
|
2. Generate a migration which will add a `versions` table to your database.
|
48
48
|
|
@@ -57,14 +57,14 @@ The Rails 2.3 code is on the [`rails2`](https://github.com/airblade/paper_trail/
|
|
57
57
|
### Sinatra
|
58
58
|
|
59
59
|
In order to configure `PaperTrail` for usage with [Sinatra](http://www.sinatrarb.com),
|
60
|
-
your `Sinatra` app must be using `ActiveRecord` 3 or `ActiveRecord` 4. It is also recommended to use the
|
60
|
+
your `Sinatra` app must be using `ActiveRecord` 3 or `ActiveRecord` 4. It is also recommended to use the
|
61
61
|
[Sinatra ActiveRecord Extension](https://github.com/janko-m/sinatra-activerecord) or something similar for managing
|
62
62
|
your applications `ActiveRecord` connection in a manner similar to the way `Rails` does. If using the aforementioned
|
63
63
|
`Sinatra ActiveRecord Extension`, steps for setting up your app with `PaperTrail` will look something like this:
|
64
64
|
|
65
65
|
1. Add `PaperTrail` to your `Gemfile`.
|
66
66
|
|
67
|
-
`gem 'paper_trail', '~> 3.0.
|
67
|
+
`gem 'paper_trail', '~> 3.0.1'`
|
68
68
|
|
69
69
|
2. Generate a migration to add a `versions` table to your database.
|
70
70
|
|
@@ -126,11 +126,18 @@ widget.previous_version
|
|
126
126
|
# Returns the widget (not a version) as it became next.
|
127
127
|
widget.next_version
|
128
128
|
|
129
|
+
# Generates a version for a `touch` event (`widget.touch` does NOT generate a version)
|
130
|
+
widget.touch_with_version
|
131
|
+
|
129
132
|
# Turn PaperTrail off for all widgets.
|
130
|
-
Widget.paper_trail_off
|
133
|
+
Widget.paper_trail_off!
|
131
134
|
|
132
135
|
# Turn PaperTrail on for all widgets.
|
133
|
-
Widget.paper_trail_on
|
136
|
+
Widget.paper_trail_on!
|
137
|
+
|
138
|
+
# Check wheter PaperTrail is enabled for all widgets
|
139
|
+
Widget.paper_trail_enabled_for_model?
|
140
|
+
widget.paper_trail_enabled_for_model?
|
134
141
|
```
|
135
142
|
|
136
143
|
And a `PaperTrail::Version` instance has these methods:
|
@@ -408,11 +415,9 @@ You can call `previous_version` and `next_version` on an item to get it as it wa
|
|
408
415
|
>> widget = live_widget.previous_version # => widget == live_widget.versions.last.reify
|
409
416
|
>> widget = widget.previous_version # => widget == live_widget.versions[-2].reify
|
410
417
|
>> widget = widget.next_version # => widget == live_widget.versions.last.reify
|
411
|
-
>> widget.next_version #
|
418
|
+
>> widget.next_version # live_widget
|
412
419
|
```
|
413
420
|
|
414
|
-
As an aside, I'm undecided about whether `widget.previous_version.next_version` should return `nil` or `self` (i.e. `widget`). Let me know if you have a view.
|
415
|
-
|
416
421
|
If instead you have a particular `version` of an item you can navigate to the previous and next versions.
|
417
422
|
|
418
423
|
```ruby
|
@@ -459,7 +464,7 @@ You may want PaperTrail to call a different method to find out who is responsibl
|
|
459
464
|
```ruby
|
460
465
|
class ApplicationController
|
461
466
|
def user_for_paper_trail
|
462
|
-
logged_in? ? current_member : 'Public user' # or whatever
|
467
|
+
logged_in? ? current_member.id : 'Public user' # or whatever
|
463
468
|
end
|
464
469
|
end
|
465
470
|
```
|
@@ -475,15 +480,28 @@ In a console session you can manually set who is responsible like this:
|
|
475
480
|
You can avoid having to do this manually by setting your initializer to pick up the username of the current user from the OS, like this:
|
476
481
|
|
477
482
|
```ruby
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
end
|
483
|
+
# config/initializers/paper_trail.rb
|
484
|
+
if defined?(::Rails::Console)
|
485
|
+
PaperTrail.whodunnit = "#{`whoami`.strip}: console"
|
486
|
+
elsif File.basename($0) == "rake"
|
487
|
+
PaperTrail.whodunnit = "#{`whoami`.strip}: rake #{ARGV.join ' '}"
|
484
488
|
end
|
485
489
|
```
|
486
490
|
|
491
|
+
Sometimes you want to define who is responsible for a change in a small scope without overwriting value of `PaperTrail.whodunnit`. It is possible to define the `whodunnit` value for an operation inside a block like this:
|
492
|
+
|
493
|
+
```ruby
|
494
|
+
>> PaperTrail.whodunnit = 'Andy Stewart'
|
495
|
+
>> widget.whodunnit('Lucas Souza') do
|
496
|
+
>> widget.update_attributes :name => 'Wibble'
|
497
|
+
>> end
|
498
|
+
>> widget.versions.last.whodunnit # Lucas Souza
|
499
|
+
>> widget.update_attributes :name => 'Clair'
|
500
|
+
>> widget.versions.last.whodunnit # Andy Stewart
|
501
|
+
>> widget.whodunnit('Ben Atkins') { |w| w.update_attributes :name => 'Beth' } # this syntax also works
|
502
|
+
>> widget.versions.last.whodunnit # Ben Atkins
|
503
|
+
```
|
504
|
+
|
487
505
|
A version's `whodunnit` records who changed the object causing the `version` to be stored. Because a version stores the object as it looked before the change (see the table above), `whodunnit` returns who stopped the object looking like this -- not who made it look like this. Hence `whodunnit` is aliased as `terminator`.
|
488
506
|
|
489
507
|
To find out who made a version's object look that way, use `version.originator`. And to find out who made a "live" object look like it does, use `originator` on the object.
|
@@ -535,7 +553,7 @@ Alternatively you could store certain metadata for one type of version, and othe
|
|
535
553
|
|
536
554
|
If you only use custom version classes and don't use PaperTrail's built-in one, on Rails `>= 3.2` you must:
|
537
555
|
|
538
|
-
- either declare PaperTrail
|
556
|
+
- either declare the `PaperTrail::Version` class to be abstract like this (in an initializer):
|
539
557
|
|
540
558
|
```ruby
|
541
559
|
PaperTrail::Version.module_eval do
|
@@ -575,8 +593,14 @@ If you can think of a good way to achieve this, please let me know.
|
|
575
593
|
PaperTrail can restore `:has_one` associations as they were at (actually, 3 seconds before) the time.
|
576
594
|
|
577
595
|
```ruby
|
596
|
+
class Location < ActiveRecord::Base
|
597
|
+
belongs_to :treasure
|
598
|
+
has_paper_trail
|
599
|
+
end
|
600
|
+
|
578
601
|
class Treasure < ActiveRecord::Base
|
579
602
|
has_one :location
|
603
|
+
has_paper_trail
|
580
604
|
end
|
581
605
|
|
582
606
|
>> treasure.amount # 100
|
@@ -691,7 +715,7 @@ PaperTrail will call your proc with the current article and store the result in
|
|
691
715
|
N.B. You must also:
|
692
716
|
|
693
717
|
* Add your metadata columns to the `versions` table.
|
694
|
-
* Declare your metadata columns using `attr_accessible`.
|
718
|
+
* Declare your metadata columns using `attr_accessible`. (If you are using `ActiveRecord 3`, or `ActiveRecord 4` with the [ProtectedAttributes](https://github.com/rails/protected_attributes) gem)
|
695
719
|
|
696
720
|
For example:
|
697
721
|
|
@@ -724,12 +748,14 @@ end
|
|
724
748
|
|
725
749
|
Remember to add those extra columns to your `versions` table and use `attr_accessible` ;)
|
726
750
|
|
751
|
+
**NOTE FOR RAILS 4:** If you're using [Strong Parameters](https://github.com/rails/strong_parameters) in Rails 4 and have *not* included the `protected_attributes` gem, there's no need to declare your metadata columns using `attr_accessible`.
|
752
|
+
|
727
753
|
|
728
754
|
## Diffing Versions
|
729
755
|
|
730
756
|
There are two scenarios: diffing adjacent versions and diffing non-adjacent versions.
|
731
757
|
|
732
|
-
The best way to diff adjacent versions is to get PaperTrail to do it for you. If you add an `object_changes` text column to your `versions` table, either at installation time with the
|
758
|
+
The best way to diff adjacent versions is to get PaperTrail to do it for you. If you add an `object_changes` text column to your `versions` table, either at installation time with the `rails generate paper_trail:install --with-changes` option or manually, PaperTrail will store the `changes` diff (excluding any attributes PaperTrail is ignoring) in each `update` version. You can use the `version.changeset` method to retrieve it. For example:
|
733
759
|
|
734
760
|
```ruby
|
735
761
|
>> widget = Widget.create :name => 'Bob'
|
@@ -772,7 +798,7 @@ On a global level you can turn PaperTrail off like this:
|
|
772
798
|
>> PaperTrail.enabled = false
|
773
799
|
```
|
774
800
|
|
775
|
-
For example, you might want to disable PaperTrail in your Rails application's test environment to speed up your tests. This will do it (note: this gets done automatically for `RSpec and `Cucumber`, please see the [Testing section](#testing)):
|
801
|
+
For example, you might want to disable PaperTrail in your Rails application's test environment to speed up your tests. This will do it (note: this gets done automatically for `RSpec` and `Cucumber`, please see the [Testing section](#testing)):
|
776
802
|
|
777
803
|
```ruby
|
778
804
|
# in config/environments/test.rb
|
@@ -823,13 +849,13 @@ end
|
|
823
849
|
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:
|
824
850
|
|
825
851
|
```ruby
|
826
|
-
>> Widget.paper_trail_off
|
852
|
+
>> Widget.paper_trail_off!
|
827
853
|
```
|
828
854
|
|
829
855
|
And on again like this:
|
830
856
|
|
831
857
|
```ruby
|
832
|
-
>> Widget.paper_trail_on
|
858
|
+
>> Widget.paper_trail_on!
|
833
859
|
```
|
834
860
|
|
835
861
|
### Per method call
|
@@ -1055,6 +1081,7 @@ Many thanks to:
|
|
1055
1081
|
* [Vlad Bokov](https://github.com/razum2um)
|
1056
1082
|
* [Sean Marcia](https://github.com/SeanMarcia)
|
1057
1083
|
* [Chulki Lee](https://github.com/chulkilee)
|
1084
|
+
* [Lucas Souza](https://github.com/lucasas)
|
1058
1085
|
|
1059
1086
|
|
1060
1087
|
## Inspirations
|
data/gemfiles/3.0.gemfile
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'rails/generators'
|
2
|
-
require 'rails/generators/migration'
|
3
2
|
require 'rails/generators/active_record'
|
4
3
|
|
5
4
|
module PaperTrail
|
@@ -13,7 +12,7 @@ module PaperTrail
|
|
13
12
|
|
14
13
|
def create_migration_file
|
15
14
|
migration_template 'create_versions.rb', 'db/migrate/create_versions.rb'
|
16
|
-
migration_template '
|
15
|
+
migration_template 'add_object_changes_to_versions.rb', 'db/migrate/add_object_changes_to_versions.rb' if options.with_changes?
|
17
16
|
end
|
18
17
|
|
19
18
|
def self.next_migration_number(dirname)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class CreateVersions < ActiveRecord::Migration
|
2
|
-
def
|
2
|
+
def change
|
3
3
|
create_table :versions do |t|
|
4
4
|
t.string :item_type, :null => false
|
5
5
|
t.integer :item_id, :null => false
|
@@ -10,9 +10,4 @@ class CreateVersions < ActiveRecord::Migration
|
|
10
10
|
end
|
11
11
|
add_index :versions, [:item_type, :item_id]
|
12
12
|
end
|
13
|
-
|
14
|
-
def self.down
|
15
|
-
remove_index :versions, [:item_type, :item_id]
|
16
|
-
drop_table :versions
|
17
|
-
end
|
18
13
|
end
|
data/lib/paper_trail.rb
CHANGED
@@ -32,6 +32,16 @@ module PaperTrail
|
|
32
32
|
!!paper_trail_store[:request_enabled_for_controller]
|
33
33
|
end
|
34
34
|
|
35
|
+
# Sets whether PaperTrail is enabled or disabled for this model in the current request.
|
36
|
+
def self.enabled_for_model(model, value)
|
37
|
+
paper_trail_store[:"enabled_for_#{model}"] = value
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns `true` if PaperTrail is enabled for this model in the current request, `false` otherwise.
|
41
|
+
def self.enabled_for_model?(model)
|
42
|
+
!!paper_trail_store.fetch(:"enabled_for_#{model}", true)
|
43
|
+
end
|
44
|
+
|
35
45
|
# Set the field which records when a version was created.
|
36
46
|
def self.timestamp_field=(field_name)
|
37
47
|
PaperTrail.config.timestamp_field = field_name
|
@@ -79,7 +89,7 @@ module PaperTrail
|
|
79
89
|
end
|
80
90
|
|
81
91
|
def self.active_record_protected_attributes?
|
82
|
-
@active_record_protected_attributes ||= ::ActiveRecord::VERSION::
|
92
|
+
@active_record_protected_attributes ||= ::ActiveRecord::VERSION::MAJOR < 4 || !!defined?(ProtectedAttributes)
|
83
93
|
end
|
84
94
|
|
85
95
|
private
|
@@ -3,7 +3,7 @@ module PaperTrail
|
|
3
3
|
module Controller
|
4
4
|
|
5
5
|
def self.included(base)
|
6
|
-
if defined?(ActionController) && base == ActionController::Base
|
6
|
+
if defined?(ActionController) && (base == ActionController::Base || base == ActionController::API)
|
7
7
|
base.before_filter :set_paper_trail_enabled_for_controller
|
8
8
|
base.before_filter :set_paper_trail_whodunnit, :set_paper_trail_controller_info
|
9
9
|
end
|
@@ -17,7 +17,7 @@ module PaperTrail
|
|
17
17
|
# Override this method in your controller to call a different
|
18
18
|
# method, e.g. `current_person`, or anything you like.
|
19
19
|
def user_for_paper_trail
|
20
|
-
current_user if defined?(current_user)
|
20
|
+
current_user.try(:id) if defined?(current_user)
|
21
21
|
end
|
22
22
|
|
23
23
|
# Returns any information about the controller or request that you
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'rspec/core'
|
2
2
|
require 'rspec/matchers'
|
3
|
-
require
|
3
|
+
require 'paper_trail/frameworks/rspec/helpers'
|
4
4
|
|
5
5
|
RSpec.configure do |config|
|
6
|
-
config.include ::PaperTrail::RSpec::
|
6
|
+
config.include ::PaperTrail::RSpec::Helpers::InstanceMethods
|
7
|
+
config.extend ::PaperTrail::RSpec::Helpers::ClassMethods
|
7
8
|
|
8
9
|
config.before(:each) do
|
9
10
|
::PaperTrail.enabled = false
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module PaperTrail
|
2
|
+
module RSpec
|
3
|
+
module Helpers
|
4
|
+
module InstanceMethods
|
5
|
+
# enable versioning for specific blocks (at instance-level)
|
6
|
+
def with_versioning
|
7
|
+
was_enabled = ::PaperTrail.enabled?
|
8
|
+
::PaperTrail.enabled = true
|
9
|
+
yield
|
10
|
+
ensure
|
11
|
+
::PaperTrail.enabled = was_enabled
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
# enable versioning for specific blocks (at class-level)
|
17
|
+
def with_versioning(&block)
|
18
|
+
context 'with versioning', :versioning => true do
|
19
|
+
class_exec(&block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -15,7 +15,7 @@ module PaperTrail
|
|
15
15
|
# Override this method in your controller to call a different
|
16
16
|
# method, e.g. `current_person`, or anything you like.
|
17
17
|
def user_for_paper_trail
|
18
|
-
current_user if defined?(current_user)
|
18
|
+
current_user.try(:id) if defined?(current_user)
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
@@ -14,11 +14,11 @@ module PaperTrail
|
|
14
14
|
# `:create`, `:update`, `:destroy` as desired.
|
15
15
|
# :class_name the name of a custom Version class. This class should inherit from `PaperTrail::Version`.
|
16
16
|
# :ignore an array of attributes for which a new `Version` will not be created if only they change.
|
17
|
-
# it can also aceept a Hash as an argument where the key is the attribute to ignore (a `String` or `Symbol`),
|
17
|
+
# it can also aceept a Hash as an argument where the key is the attribute to ignore (a `String` or `Symbol`),
|
18
18
|
# which will only be ignored if the value is a `Proc` which returns truthily.
|
19
19
|
# :if, :unless Procs that allow to specify conditions when to save versions for an object
|
20
20
|
# :only inverse of `ignore` - a new `Version` will be created only for these attributes if supplied
|
21
|
-
# it can also aceept a Hash as an argument where the key is the attribute to track (a `String` or `Symbol`),
|
21
|
+
# it can also aceept a Hash as an argument where the key is the attribute to track (a `String` or `Symbol`),
|
22
22
|
# which will only be counted if the value is a `Proc` which returns truthily.
|
23
23
|
# :skip fields to ignore completely. As with `ignore`, updates to these fields will not create
|
24
24
|
# a new `Version`. In addition, these fields will not be included in the serialized versions
|
@@ -54,15 +54,12 @@ module PaperTrail
|
|
54
54
|
|
55
55
|
paper_trail_options[:meta] ||= {}
|
56
56
|
|
57
|
-
class_attribute :paper_trail_enabled_for_model
|
58
|
-
self.paper_trail_enabled_for_model = true
|
59
|
-
|
60
57
|
class_attribute :versions_association_name
|
61
58
|
self.versions_association_name = options[:versions] || :versions
|
62
59
|
|
63
60
|
attr_accessor :paper_trail_event
|
64
61
|
|
65
|
-
if ::ActiveRecord::VERSION::
|
62
|
+
if ::ActiveRecord::VERSION::MAJOR >= 4 # `has_many` syntax for specifying order uses a lambda in Rails 4
|
66
63
|
has_many self.versions_association_name,
|
67
64
|
lambda { order("#{PaperTrail.timestamp_field} ASC") },
|
68
65
|
:class_name => self.version_class_name, :as => :item
|
@@ -80,13 +77,27 @@ module PaperTrail
|
|
80
77
|
end
|
81
78
|
|
82
79
|
# Switches PaperTrail off for this class.
|
80
|
+
def paper_trail_off!
|
81
|
+
PaperTrail.enabled_for_model(self, false)
|
82
|
+
end
|
83
|
+
|
83
84
|
def paper_trail_off
|
84
|
-
|
85
|
+
warn "DEPRECATED: use `paper_trail_off!` instead of `paper_trail_off`. Support for `paper_trail_off` will be removed in PaperTrail 3.1"
|
86
|
+
self.paper_trail_off!
|
85
87
|
end
|
86
88
|
|
87
89
|
# Switches PaperTrail on for this class.
|
88
|
-
def paper_trail_on
|
89
|
-
self
|
90
|
+
def paper_trail_on!
|
91
|
+
PaperTrail.enabled_for_model(self, true)
|
92
|
+
end
|
93
|
+
|
94
|
+
def paper_trail_on
|
95
|
+
warn "DEPRECATED: use `paper_trail_on!` instead of `paper_trail_on`. Support for `paper_trail_on` will be removed in PaperTrail 3.1"
|
96
|
+
self.paper_trail_on!
|
97
|
+
end
|
98
|
+
|
99
|
+
def paper_trail_enabled_for_model?
|
100
|
+
PaperTrail.enabled_for_model?(self)
|
90
101
|
end
|
91
102
|
|
92
103
|
def paper_trail_version_class
|
@@ -192,13 +203,43 @@ module PaperTrail
|
|
192
203
|
nil
|
193
204
|
end
|
194
205
|
|
206
|
+
def paper_trail_enabled_for_model?
|
207
|
+
self.class.paper_trail_enabled_for_model?
|
208
|
+
end
|
209
|
+
|
195
210
|
# Executes the given method or block without creating a new version.
|
196
211
|
def without_versioning(method = nil)
|
197
|
-
paper_trail_was_enabled = self.paper_trail_enabled_for_model
|
198
|
-
self.class.paper_trail_off
|
199
|
-
method ? method.to_proc.call(self) : yield
|
212
|
+
paper_trail_was_enabled = self.paper_trail_enabled_for_model?
|
213
|
+
self.class.paper_trail_off!
|
214
|
+
method ? method.to_proc.call(self) : yield(self)
|
215
|
+
ensure
|
216
|
+
self.class.paper_trail_on! if paper_trail_was_enabled
|
217
|
+
end
|
218
|
+
|
219
|
+
# Temporarily overwrites the value of whodunnit and then executes the provided block.
|
220
|
+
def whodunnit(value)
|
221
|
+
raise ArgumentError, 'expected to receive a block' unless block_given?
|
222
|
+
current_whodunnit = PaperTrail.whodunnit
|
223
|
+
PaperTrail.whodunnit = value
|
224
|
+
yield self
|
200
225
|
ensure
|
201
|
-
|
226
|
+
PaperTrail.whodunnit = current_whodunnit
|
227
|
+
end
|
228
|
+
|
229
|
+
# Mimicks behavior of `touch` method from `ActiveRecord::Persistence`, but generates a version
|
230
|
+
#
|
231
|
+
# TODO: lookinto leveraging the `after_touch` callback from `ActiveRecord` to allow the
|
232
|
+
# regular `touch` method go generate a version as normal. May make sense to switch the `record_update`
|
233
|
+
# method to leverage an `after_update` callback anyways (likely for v3.1.0)
|
234
|
+
def touch_with_version(name = nil)
|
235
|
+
raise ActiveRecordError, "can not touch on a new record object" unless persisted?
|
236
|
+
|
237
|
+
attributes = timestamp_attributes_for_update_in_model
|
238
|
+
attributes << name if name
|
239
|
+
current_time = current_time_from_proper_timezone
|
240
|
+
|
241
|
+
attributes.each { |column| write_attribute(column, current_time) }
|
242
|
+
save!
|
202
243
|
end
|
203
244
|
|
204
245
|
private
|
@@ -323,7 +364,7 @@ module PaperTrail
|
|
323
364
|
end
|
324
365
|
|
325
366
|
def paper_trail_switched_on?
|
326
|
-
PaperTrail.enabled? && PaperTrail.enabled_for_controller? && self.paper_trail_enabled_for_model
|
367
|
+
PaperTrail.enabled? && PaperTrail.enabled_for_controller? && self.paper_trail_enabled_for_model?
|
327
368
|
end
|
328
369
|
|
329
370
|
def save_version?
|
data/paper_trail.gemspec
CHANGED
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.add_development_dependency 'sinatra', '~> 1.0'
|
31
31
|
s.add_development_dependency 'rack-test', '>= 0.6'
|
32
32
|
s.add_development_dependency 'rspec-rails', '~> 2.14'
|
33
|
+
s.add_development_dependency 'generator_spec'
|
33
34
|
|
34
35
|
# JRuby support for the test ENV
|
35
36
|
unless defined?(JRUBY_VERSION)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'generator_spec/test_case'
|
3
|
+
require File.expand_path('../../../lib/generators/paper_trail/install_generator', __FILE__)
|
4
|
+
|
5
|
+
describe PaperTrail::InstallGenerator, :type => :generator do
|
6
|
+
include GeneratorSpec::TestCase
|
7
|
+
destination File.expand_path('../tmp', __FILE__)
|
8
|
+
|
9
|
+
after(:all) { prepare_destination } # cleanup the tmp directory
|
10
|
+
|
11
|
+
describe "no options" do
|
12
|
+
before(:all) do
|
13
|
+
prepare_destination
|
14
|
+
run_generator
|
15
|
+
end
|
16
|
+
|
17
|
+
it "generates a migration for creating the 'versions' table" do
|
18
|
+
destination_root.should have_structure {
|
19
|
+
directory 'db' do
|
20
|
+
directory 'migrate' do
|
21
|
+
migration 'create_versions' do
|
22
|
+
contains 'class CreateVersions'
|
23
|
+
contains 'def change'
|
24
|
+
contains 'create_table :versions do |t|'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "`--with-changes` option set to `true`" do
|
33
|
+
before(:all) do
|
34
|
+
prepare_destination
|
35
|
+
run_generator %w(--with-changes)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "generates a migration for creating the 'versions' table" do
|
39
|
+
destination_root.should have_structure {
|
40
|
+
directory 'db' do
|
41
|
+
directory 'migrate' do
|
42
|
+
migration 'create_versions' do
|
43
|
+
contains 'class CreateVersions'
|
44
|
+
contains 'def change'
|
45
|
+
contains 'create_table :versions do |t|'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
it "generates a migration for adding the 'object_changes' column to the 'versions' table" do
|
53
|
+
destination_root.should have_structure {
|
54
|
+
directory 'db' do
|
55
|
+
directory 'migrate' do
|
56
|
+
migration 'add_object_changes_to_versions' do
|
57
|
+
contains 'class AddObjectChangesToVersions'
|
58
|
+
contains 'def change'
|
59
|
+
contains 'add_column :versions, :object_changes, :text'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/spec/models/widget_spec.rb
CHANGED
@@ -5,9 +5,9 @@ describe Widget do
|
|
5
5
|
it { should be_versioned }
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
let(:widget) { Widget.create :name => 'Bob', :an_integer => 1 }
|
8
|
+
let(:widget) { Widget.create :name => 'Bob', :an_integer => 1 }
|
10
9
|
|
10
|
+
describe "`versioning` option" do
|
11
11
|
context :enabled, :versioning => true do
|
12
12
|
it 'should enable versioning for models wrapped within a block' do
|
13
13
|
widget.versions.size.should == 1
|
@@ -20,4 +20,122 @@ describe Widget do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
describe "Methods" do
|
25
|
+
describe "Instance", :versioning => true do
|
26
|
+
describe :whodunnit do
|
27
|
+
it { should respond_to(:whodunnit) }
|
28
|
+
|
29
|
+
context "no block given" do
|
30
|
+
it "should raise an error" do
|
31
|
+
expect { widget.whodunnit('Ben') }.to raise_error(ArgumentError, 'expected to receive a block')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "block given" do
|
36
|
+
let(:orig_name) { Faker::Name.name }
|
37
|
+
let(:new_name) { Faker::Name.name }
|
38
|
+
|
39
|
+
before do
|
40
|
+
PaperTrail.whodunnit = orig_name
|
41
|
+
widget.versions.last.whodunnit.should == orig_name # persist `widget`
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should modify value of `PaperTrail.whodunnit` while executing the block" do
|
45
|
+
widget.whodunnit(new_name) do
|
46
|
+
PaperTrail.whodunnit.should == new_name
|
47
|
+
widget.update_attributes(:name => 'Elizabeth')
|
48
|
+
end
|
49
|
+
widget.versions.last.whodunnit.should == new_name
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should revert the value of `PaperTrail.whodunnit` to it's previous value after executing the block" do
|
53
|
+
widget.whodunnit(new_name) { |w| w.update_attributes(:name => 'Elizabeth') }
|
54
|
+
PaperTrail.whodunnit.should == orig_name
|
55
|
+
end
|
56
|
+
|
57
|
+
context "error within block" do
|
58
|
+
it "should ensure that the whodunnit value still reverts to it's previous value" do
|
59
|
+
expect { widget.whodunnit(new_name) { raise } }.to raise_error
|
60
|
+
PaperTrail.whodunnit.should == orig_name
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe :touch_with_version do
|
67
|
+
it { should respond_to(:touch_with_version) }
|
68
|
+
|
69
|
+
it "should generate a version" do
|
70
|
+
count = widget.versions.size
|
71
|
+
widget.touch_with_version
|
72
|
+
widget.versions.size.should == count + 1
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should increment the `:updated_at` timestamp" do
|
76
|
+
time_was = widget.updated_at
|
77
|
+
widget.touch_with_version
|
78
|
+
widget.updated_at.should > time_was
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "Class" do
|
84
|
+
subject { Widget }
|
85
|
+
|
86
|
+
describe :paper_trail_off! do
|
87
|
+
it { should respond_to(:paper_trail_off!) }
|
88
|
+
|
89
|
+
it 'should set the `paper_trail_enabled_for_model?` to `false`' do
|
90
|
+
subject.paper_trail_enabled_for_model?.should be_true
|
91
|
+
subject.paper_trail_off!
|
92
|
+
subject.paper_trail_enabled_for_model?.should be_false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe :paper_trail_off do
|
97
|
+
it { should respond_to(:paper_trail_off) }
|
98
|
+
|
99
|
+
it 'should set the invoke `paper_trail_off!`' do
|
100
|
+
subject.should_receive(:warn)
|
101
|
+
subject.should_receive(:paper_trail_off!)
|
102
|
+
subject.paper_trail_off
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should display a deprecation warning' do
|
106
|
+
subject.should_receive(:warn).with("DEPRECATED: use `paper_trail_on!` instead of `paper_trail_on`. Support for `paper_trail_on` will be removed in PaperTrail 3.1")
|
107
|
+
subject.paper_trail_on
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe :paper_trail_on! do
|
112
|
+
before { subject.paper_trail_off! }
|
113
|
+
|
114
|
+
it { should respond_to(:paper_trail_on!) }
|
115
|
+
|
116
|
+
it 'should set the `paper_trail_enabled_for_model?` to `true`' do
|
117
|
+
subject.paper_trail_enabled_for_model?.should be_false
|
118
|
+
subject.paper_trail_on!
|
119
|
+
subject.paper_trail_enabled_for_model?.should be_true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe :paper_trail_on do
|
124
|
+
before { subject.paper_trail_off! }
|
125
|
+
|
126
|
+
it { should respond_to(:paper_trail_on) }
|
127
|
+
|
128
|
+
it 'should set the invoke `paper_trail_on!`' do
|
129
|
+
subject.should_receive(:warn)
|
130
|
+
subject.should_receive(:paper_trail_on!)
|
131
|
+
subject.paper_trail_on
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should display a deprecation warning' do
|
135
|
+
subject.should_receive(:warn).with("DEPRECATED: use `paper_trail_on!` instead of `paper_trail_on`. Support for `paper_trail_on` will be removed in PaperTrail 3.1")
|
136
|
+
subject.paper_trail_on
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
23
141
|
end
|
data/spec/paper_trail_spec.rb
CHANGED
@@ -5,13 +5,21 @@ describe "PaperTrail RSpec Helper" do
|
|
5
5
|
it 'should have versioning off by default' do
|
6
6
|
::PaperTrail.should_not be_enabled
|
7
7
|
end
|
8
|
-
it 'should turn versioning on in a with_versioning block' do
|
8
|
+
it 'should turn versioning on in a `with_versioning` block' do
|
9
9
|
::PaperTrail.should_not be_enabled
|
10
10
|
with_versioning do
|
11
11
|
::PaperTrail.should be_enabled
|
12
12
|
end
|
13
13
|
::PaperTrail.should_not be_enabled
|
14
14
|
end
|
15
|
+
|
16
|
+
context "error within `with_versioning` block" do
|
17
|
+
it "should revert the value of `PaperTrail.enabled?` to it's previous state" do
|
18
|
+
::PaperTrail.should_not be_enabled
|
19
|
+
expect { with_versioning { raise } }.to raise_error
|
20
|
+
::PaperTrail.should_not be_enabled
|
21
|
+
end
|
22
|
+
end
|
15
23
|
end
|
16
24
|
|
17
25
|
context '`versioning: true`', :versioning => true do
|
@@ -27,6 +35,19 @@ describe "PaperTrail RSpec Helper" do
|
|
27
35
|
end
|
28
36
|
end
|
29
37
|
|
38
|
+
context '`with_versioning` block at class level' do
|
39
|
+
it { ::PaperTrail.should_not be_enabled }
|
40
|
+
|
41
|
+
with_versioning do
|
42
|
+
it 'should have versioning on by default' do
|
43
|
+
::PaperTrail.should be_enabled
|
44
|
+
end
|
45
|
+
end
|
46
|
+
it 'should not leak the `enabled?` state into successive tests' do
|
47
|
+
::PaperTrail.should_not be_enabled
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
30
51
|
describe :whodunnit do
|
31
52
|
before(:all) { ::PaperTrail.whodunnit = 'foobar' }
|
32
53
|
|
@@ -1,23 +1,19 @@
|
|
1
|
-
RSpec.configure do |c|
|
2
|
-
c.order = 'defined'
|
3
|
-
end
|
4
|
-
|
5
1
|
require 'spec_helper'
|
6
2
|
|
7
3
|
describe "Articles" do
|
8
4
|
let(:valid_params) { { :article => { :title => 'Doh', :content => Faker::Lorem.sentence } } }
|
9
5
|
|
10
6
|
context "versioning disabled" do
|
11
|
-
specify { PaperTrail.
|
7
|
+
specify { PaperTrail.should_not be_enabled }
|
12
8
|
|
13
9
|
it "should not create a version" do
|
14
|
-
PaperTrail.
|
10
|
+
PaperTrail.should be_enabled_for_controller
|
15
11
|
expect { post articles_path(valid_params) }.to_not change(PaperTrail::Version, :count)
|
16
|
-
PaperTrail.
|
12
|
+
PaperTrail.should_not be_enabled_for_controller
|
17
13
|
end
|
18
14
|
|
19
|
-
it "should not leak the state of the `PaperTrail.
|
20
|
-
PaperTrail.
|
15
|
+
it "should not leak the state of the `PaperTrail.enabled_for_controller?` into the next test" do
|
16
|
+
PaperTrail.should be_enabled_for_controller
|
21
17
|
end
|
22
18
|
end
|
23
19
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,7 +7,10 @@ class ApplicationController < ActionController::Base
|
|
7
7
|
|
8
8
|
# Returns id of hypothetical current user
|
9
9
|
def current_user
|
10
|
-
153
|
10
|
+
@current_user ||= OpenStruct.new(:id => 153).tap do |obj|
|
11
|
+
# Invoking `id` returns the `object_id` value in Ruby18 unless specifically overwritten
|
12
|
+
def obj.id; 153; end if RUBY_VERSION.to_f < 1.9
|
13
|
+
end
|
11
14
|
end
|
12
15
|
|
13
16
|
def info_for_paper_trail
|
@@ -2,7 +2,7 @@ class Widget < ActiveRecord::Base
|
|
2
2
|
has_paper_trail
|
3
3
|
has_one :wotsit
|
4
4
|
|
5
|
-
if ActiveRecord::VERSION::
|
5
|
+
if ::ActiveRecord::VERSION::MAJOR >= 4 # `has_many` syntax for specifying order uses a lambda in Rails 4
|
6
6
|
has_many :fluxors, lambda { order(:name) }
|
7
7
|
else
|
8
8
|
has_many :fluxors, :order => :name
|
@@ -10,9 +10,9 @@ class SetUpTestTables < ActiveRecord::Migration
|
|
10
10
|
t.time :a_time
|
11
11
|
t.date :a_date
|
12
12
|
t.boolean :a_boolean
|
13
|
-
t.datetime :created_at, :updated_at
|
14
13
|
t.string :sacrificial_column
|
15
14
|
t.string :type
|
15
|
+
t.timestamps
|
16
16
|
end
|
17
17
|
|
18
18
|
create_table :versions, :force => true do |t|
|
@@ -54,7 +54,7 @@ class SetUpTestTables < ActiveRecord::Migration
|
|
54
54
|
create_table :wotsits, :force => true do |t|
|
55
55
|
t.integer :widget_id
|
56
56
|
t.string :name
|
57
|
-
t.
|
57
|
+
t.timestamps
|
58
58
|
end
|
59
59
|
|
60
60
|
create_table :fluxors, :force => true do |t|
|
data/test/dummy/db/schema.rb
CHANGED
@@ -71,6 +71,7 @@ ActiveRecord::Schema.define(:version => 20110208155312) do
|
|
71
71
|
t.integer "article_id"
|
72
72
|
t.string "ip"
|
73
73
|
t.string "user_agent"
|
74
|
+
t.text :object_changes
|
74
75
|
end
|
75
76
|
|
76
77
|
add_index "versions", ["item_type", "item_id"], :name => "index_versions_on_item_type_and_item_id"
|
@@ -12,7 +12,10 @@ class BaseApp < Sinatra::Base
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def current_user
|
15
|
-
'foobar'
|
15
|
+
@current_user ||= OpenStruct.new(:id => 'foobar').tap do |obj|
|
16
|
+
# Invoking `id` returns the `object_id` value in Ruby18 unless specifically overwritten
|
17
|
+
def obj.id; 'foobar'; end if RUBY_VERSION.to_f < 1.9
|
18
|
+
end
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
@@ -12,7 +12,10 @@ class Sinatra::Application
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def current_user
|
15
|
-
'raboof'
|
15
|
+
@current_user ||= OpenStruct.new(:id => 'raboof').tap do |obj|
|
16
|
+
# Invoking `id` returns the `object_id` value in Ruby18 unless specifically overwritten
|
17
|
+
def obj.id; 'raboof'; end if RUBY_VERSION.to_f < 1.9
|
18
|
+
end
|
16
19
|
end
|
17
20
|
|
18
21
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class ThreadSafetyTest < ActionController::TestCase
|
4
|
-
test "be thread safe" do
|
4
|
+
test "be thread safe when using #set_paper_trail_whodunnit" do
|
5
5
|
blocked = true
|
6
6
|
|
7
7
|
slow_thread = Thread.new do
|
@@ -23,4 +23,26 @@ class ThreadSafetyTest < ActionController::TestCase
|
|
23
23
|
|
24
24
|
assert_not_equal slow_thread.value, fast_thread.value
|
25
25
|
end
|
26
|
+
|
27
|
+
test "be thread safe when using #without_versioning" do
|
28
|
+
enabled = nil
|
29
|
+
|
30
|
+
slow_thread = Thread.new do
|
31
|
+
Widget.new.without_versioning do
|
32
|
+
sleep(0.01)
|
33
|
+
enabled = Widget.paper_trail_enabled_for_model?
|
34
|
+
sleep(0.01)
|
35
|
+
end
|
36
|
+
enabled
|
37
|
+
end
|
38
|
+
|
39
|
+
fast_thread = Thread.new do
|
40
|
+
sleep(0.005)
|
41
|
+
Widget.paper_trail_enabled_for_model?
|
42
|
+
end
|
43
|
+
|
44
|
+
assert_not_equal slow_thread.value, fast_thread.value
|
45
|
+
assert Widget.paper_trail_enabled_for_model?
|
46
|
+
assert PaperTrail.enabled_for_model?(Widget)
|
47
|
+
end
|
26
48
|
end
|
data/test/unit/model_test.rb
CHANGED
@@ -478,11 +478,11 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
478
478
|
|
479
479
|
context 'with its paper trail turned off' do
|
480
480
|
setup do
|
481
|
-
Widget.paper_trail_off
|
481
|
+
Widget.paper_trail_off!
|
482
482
|
@count = @widget.versions.length
|
483
483
|
end
|
484
484
|
|
485
|
-
teardown { Widget.paper_trail_on }
|
485
|
+
teardown { Widget.paper_trail_on! }
|
486
486
|
|
487
487
|
context 'when updated' do
|
488
488
|
setup { @widget.update_attributes :name => 'Beeblebrox' }
|
@@ -495,12 +495,12 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
495
495
|
context 'when destroyed "without versioning"' do
|
496
496
|
should 'leave paper trail off after call' do
|
497
497
|
@widget.without_versioning :destroy
|
498
|
-
assert !Widget.paper_trail_enabled_for_model
|
498
|
+
assert !Widget.paper_trail_enabled_for_model?
|
499
499
|
end
|
500
500
|
end
|
501
501
|
|
502
502
|
context 'and then its paper trail turned on' do
|
503
|
-
setup { Widget.paper_trail_on }
|
503
|
+
setup { Widget.paper_trail_on! }
|
504
504
|
|
505
505
|
context 'when updated' do
|
506
506
|
setup { @widget.update_attributes :name => 'Ford' }
|
@@ -515,14 +515,28 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
515
515
|
@widget.without_versioning do
|
516
516
|
@widget.update_attributes :name => 'Ford'
|
517
517
|
end
|
518
|
+
# The model instance should yield itself for convenience purposes
|
519
|
+
@widget.without_versioning { |w| w.update_attributes :name => 'Nixon' }
|
518
520
|
end
|
519
521
|
|
520
522
|
should 'not create new version' do
|
521
|
-
assert_equal
|
523
|
+
assert_equal @count, @widget.versions.length
|
522
524
|
end
|
523
525
|
|
524
526
|
should 'enable paper trail after call' do
|
525
|
-
assert Widget.paper_trail_enabled_for_model
|
527
|
+
assert Widget.paper_trail_enabled_for_model?
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
context 'when receiving a method name as an argument' do
|
532
|
+
setup { @widget.without_versioning(:touch_with_version) }
|
533
|
+
|
534
|
+
should 'not create new version' do
|
535
|
+
assert_equal @count, @widget.versions.length
|
536
|
+
end
|
537
|
+
|
538
|
+
should 'enable paper trail after call' do
|
539
|
+
assert Widget.paper_trail_enabled_for_model?
|
526
540
|
end
|
527
541
|
end
|
528
542
|
end
|
@@ -615,7 +629,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
615
629
|
|
616
630
|
should 'reify with the correct type' do
|
617
631
|
# For some reason this test appears to be broken on AR4 in the test env. Executing it manually in the Rails console seems to work.. not sure what the issues is here.
|
618
|
-
assert_kind_of FooWidget, @foo.versions.last.reify if ActiveRecord::VERSION::
|
632
|
+
assert_kind_of FooWidget, @foo.versions.last.reify if ActiveRecord::VERSION::MAJOR < 4
|
619
633
|
assert_equal @foo.versions.first, PaperTrail::Version.last.previous
|
620
634
|
assert_nil PaperTrail::Version.last.next
|
621
635
|
end
|
@@ -771,7 +785,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
771
785
|
should 'store dynamic meta data based on a method of the item' do
|
772
786
|
assert_equal @article.action_data_provider_method, @article.versions.last.action
|
773
787
|
end
|
774
|
-
|
788
|
+
|
775
789
|
should 'store dynamic meta data based on an attribute of the item prior to creation' do
|
776
790
|
assert_equal nil, @article.versions.last.title
|
777
791
|
end
|
@@ -793,7 +807,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
793
807
|
should 'store dynamic meta data which depends on the item' do
|
794
808
|
assert_equal @article.id, @article.versions.last.article_id
|
795
809
|
end
|
796
|
-
|
810
|
+
|
797
811
|
should 'store dynamic meta data based on an attribute of the item prior to the update' do
|
798
812
|
assert_equal @initial_title, @article.versions.last.title
|
799
813
|
end
|
@@ -814,7 +828,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
814
828
|
should 'store dynamic meta data which depends on the item' do
|
815
829
|
assert_equal @article.id, @article.versions.last.article_id
|
816
830
|
end
|
817
|
-
|
831
|
+
|
818
832
|
should 'store dynamic meta data based on an attribute of the item prior to the destruction' do
|
819
833
|
assert_equal @initial_title, @article.versions.last.title
|
820
834
|
end
|
@@ -837,7 +851,6 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
837
851
|
should 'return its previous self' do
|
838
852
|
assert_equal @widget.versions[-2].reify, @widget.previous_version
|
839
853
|
end
|
840
|
-
|
841
854
|
end
|
842
855
|
|
843
856
|
|
@@ -1060,7 +1073,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
1060
1073
|
end
|
1061
1074
|
# Need an additional clause to detect what version of ActiveRecord is being used for this test because AR4 injects the `updated_at` column into the changeset for updates to models
|
1062
1075
|
should 'version.object_changes should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
|
1063
|
-
assert @person.versions.last.object_changes.length < (ActiveRecord::VERSION::
|
1076
|
+
assert @person.versions.last.object_changes.length < (ActiveRecord::VERSION::MAJOR < 4 ? 105 : 118), "object_changes length was #{@person.versions.last.object_changes.length}"
|
1064
1077
|
end
|
1065
1078
|
# But now it stores the short, serialized value.
|
1066
1079
|
should 'version.object attribute should have stored the value returned by the attribute serializer' do
|
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
3
3
|
class ProtectedAttrsTest < ActiveSupport::TestCase
|
4
4
|
subject { ProtectedWidget.new }
|
5
5
|
|
6
|
-
if ActiveRecord::VERSION::
|
6
|
+
if ActiveRecord::VERSION::MAJOR < 4 # these ActiveModel matchers (provided by shoulda-matchers) only work for Rails 3
|
7
7
|
accessible_attrs = ProtectedWidget.accessible_attributes.to_a
|
8
8
|
accessible_attrs.each do |attr_name|
|
9
9
|
should allow_mass_assignment_of(attr_name.to_sym)
|
@@ -36,7 +36,7 @@ class ProtectedAttrsTest < ActiveSupport::TestCase
|
|
36
36
|
|
37
37
|
should 'the previous version should contain right attributes' do
|
38
38
|
# For some reason this test seems to be broken in JRuby 1.9 mode in the test env even though it works in the console. WTF?
|
39
|
-
unless ActiveRecord::VERSION::
|
39
|
+
unless ActiveRecord::VERSION::MAJOR >= 4 && defined?(JRUBY_VERSION) && RUBY_VERSION.to_f >= 1.9
|
40
40
|
assert_equal @widget.previous_version.attributes, @initial_attributes
|
41
41
|
end
|
42
42
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paper_trail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Stewart
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-03-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -155,6 +155,20 @@ dependencies:
|
|
155
155
|
- - ~>
|
156
156
|
- !ruby/object:Gem::Version
|
157
157
|
version: '2.14'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: generator_spec
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - '>='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
type: :development
|
166
|
+
prerelease: false
|
167
|
+
version_requirements: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - '>='
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
158
172
|
- !ruby/object:Gem::Dependency
|
159
173
|
name: sqlite3
|
160
174
|
requirement: !ruby/object:Gem::Requirement
|
@@ -186,7 +200,7 @@ files:
|
|
186
200
|
- gemfiles/3.0.gemfile
|
187
201
|
- lib/generators/paper_trail/USAGE
|
188
202
|
- lib/generators/paper_trail/install_generator.rb
|
189
|
-
- lib/generators/paper_trail/templates/
|
203
|
+
- lib/generators/paper_trail/templates/add_object_changes_to_versions.rb
|
190
204
|
- lib/generators/paper_trail/templates/create_versions.rb
|
191
205
|
- lib/paper_trail.rb
|
192
206
|
- lib/paper_trail/cleaner.rb
|
@@ -194,7 +208,7 @@ files:
|
|
194
208
|
- lib/paper_trail/frameworks/cucumber.rb
|
195
209
|
- lib/paper_trail/frameworks/rails.rb
|
196
210
|
- lib/paper_trail/frameworks/rspec.rb
|
197
|
-
- lib/paper_trail/frameworks/rspec/
|
211
|
+
- lib/paper_trail/frameworks/rspec/helpers.rb
|
198
212
|
- lib/paper_trail/frameworks/sinatra.rb
|
199
213
|
- lib/paper_trail/has_paper_trail.rb
|
200
214
|
- lib/paper_trail/serializers/json.rb
|
@@ -203,6 +217,7 @@ files:
|
|
203
217
|
- lib/paper_trail/version_concern.rb
|
204
218
|
- lib/paper_trail/version_number.rb
|
205
219
|
- paper_trail.gemspec
|
220
|
+
- spec/generators/install_generator_spec.rb
|
206
221
|
- spec/models/joined_version_spec.rb
|
207
222
|
- spec/models/version_spec.rb
|
208
223
|
- spec/models/widget_spec.rb
|
@@ -307,11 +322,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
307
322
|
version: 1.3.6
|
308
323
|
requirements: []
|
309
324
|
rubyforge_project:
|
310
|
-
rubygems_version: 2.1
|
325
|
+
rubygems_version: 2.2.1
|
311
326
|
signing_key:
|
312
327
|
specification_version: 4
|
313
328
|
summary: Track changes to your models' data. Good for auditing or versioning.
|
314
329
|
test_files:
|
330
|
+
- spec/generators/install_generator_spec.rb
|
315
331
|
- spec/models/joined_version_spec.rb
|
316
332
|
- spec/models/version_spec.rb
|
317
333
|
- spec/models/widget_spec.rb
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module PaperTrail
|
2
|
-
module RSpec
|
3
|
-
module Extensions
|
4
|
-
# :call-seq:
|
5
|
-
# with_versioning
|
6
|
-
#
|
7
|
-
# enable versioning for specific blocks
|
8
|
-
|
9
|
-
def with_versioning
|
10
|
-
was_enabled = ::PaperTrail.enabled?
|
11
|
-
::PaperTrail.enabled = true
|
12
|
-
begin
|
13
|
-
yield
|
14
|
-
ensure
|
15
|
-
::PaperTrail.enabled = was_enabled
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|