paper_trail 2.2.6 → 2.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +13 -3
- data/lib/generators/paper_trail/install_generator.rb +2 -0
- data/lib/generators/paper_trail/templates/add_object_changes_column_to_versions.rb +9 -0
- data/lib/paper_trail/has_paper_trail.rb +7 -3
- data/lib/paper_trail/version.rb +5 -0
- data/lib/paper_trail/version_number.rb +1 -1
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +2 -1
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/test_helper.rb +8 -0
- data/test/unit/model_test.rb +15 -1
- metadata +5 -4
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -453,11 +453,20 @@ Remember to add those extra columns to your `versions` table ;)
|
|
453
453
|
|
454
454
|
## Diffing Versions
|
455
455
|
|
456
|
-
|
456
|
+
There are two scenarios: diffing adjacent versions and diffing non-adjacent versions.
|
457
457
|
|
458
|
-
|
458
|
+
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 `--with-changes` option or manually, PaperTrail will store the `changes` diff in each `update` version. You can use the `version.changeset` method to retrieve it. For example:
|
459
459
|
|
460
|
-
|
460
|
+
>> widget = Widget.create :name => 'Bob'
|
461
|
+
>> widget.versions.last.changeset # nil
|
462
|
+
>> widget.update_attributes :name => 'Robert'
|
463
|
+
>> widget.versions.last.changeset # {'name' => ['Bob', 'Robert']}
|
464
|
+
|
465
|
+
Note PaperTrail only stores the changes for updates; there's no point storing them for created or destroyed objects.
|
466
|
+
|
467
|
+
Please be aware that PaperTrail doesn't use diffs internally. When I designed PaperTrail I wanted simplicity and robustness so I decided to make each version of an object self-contained. A version stores all of its object's data, not a diff from the previous version. This means you can delete any version without affecting any other.
|
468
|
+
|
469
|
+
To diff non-adjacent versions you'll have to write your own code. These libraries may help:
|
461
470
|
|
462
471
|
For diffing two strings:
|
463
472
|
|
@@ -604,6 +613,7 @@ Many thanks to:
|
|
604
613
|
* [Burke Libbey](https://github.com/burke)
|
605
614
|
* [6twenty](https://github.com/6twenty)
|
606
615
|
* [nir0](https://github.com/nir0)
|
616
|
+
* [Eduard Tsech](https://github.com/edtsech)
|
607
617
|
|
608
618
|
|
609
619
|
## Inspirations
|
@@ -8,11 +8,13 @@ module PaperTrail
|
|
8
8
|
extend ActiveRecord::Generators::Migration
|
9
9
|
|
10
10
|
source_root File.expand_path('../templates', __FILE__)
|
11
|
+
class_option :with_changes, :type => :boolean, :default => false, :desc => "Store changeset (diff) with each version"
|
11
12
|
|
12
13
|
desc 'Generates (but does not run) a migration to add a versions table.'
|
13
14
|
|
14
15
|
def create_migration_file
|
15
16
|
migration_template 'create_versions.rb', 'db/migrate/create_versions.rb'
|
17
|
+
migration_template 'add_object_changes_column_to_versions.rb', 'db/migrate/add_object_changes_column_to_versions.rb' if options.with_changes?
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
@@ -109,9 +109,13 @@ module PaperTrail
|
|
109
109
|
|
110
110
|
def record_update
|
111
111
|
if switched_on? && changed_notably?
|
112
|
-
|
113
|
-
|
114
|
-
|
112
|
+
data = {
|
113
|
+
:event => 'update',
|
114
|
+
:object => object_to_string(item_before_change),
|
115
|
+
:whodunnit => PaperTrail.whodunnit
|
116
|
+
}
|
117
|
+
data[:object_changes] = self.changes.to_yaml if Version.method_defined? :object_changes
|
118
|
+
versions.build merge_metadata(data)
|
115
119
|
end
|
116
120
|
end
|
117
121
|
|
data/lib/paper_trail/version.rb
CHANGED
@@ -79,6 +79,11 @@ class Version < ActiveRecord::Base
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
+
# Returns what changed in this version of the item. Cf. `ActiveModel::Dirty#changes`.
|
83
|
+
def changeset
|
84
|
+
YAML::load(object_changes) if Version.method_defined?(:object_changes) && object_changes
|
85
|
+
end
|
86
|
+
|
82
87
|
# Returns who put the item into the state stored in this version.
|
83
88
|
def originator
|
84
89
|
previous.try :whodunnit
|
@@ -21,6 +21,7 @@ class SetUpTestTables < ActiveRecord::Migration
|
|
21
21
|
t.string :event, :null => false
|
22
22
|
t.string :whodunnit
|
23
23
|
t.text :object
|
24
|
+
t.text :object_changes
|
24
25
|
t.datetime :created_at
|
25
26
|
|
26
27
|
# Metadata columns.
|
@@ -34,7 +35,7 @@ class SetUpTestTables < ActiveRecord::Migration
|
|
34
35
|
t.string :user_agent
|
35
36
|
end
|
36
37
|
add_index :versions, [:item_type, :item_id]
|
37
|
-
|
38
|
+
|
38
39
|
create_table :post_versions, :force => true do |t|
|
39
40
|
t.string :item_type, :null => false
|
40
41
|
t.integer :item_id, :null => false
|
data/test/dummy/db/test.sqlite3
CHANGED
Binary file
|
data/test/test_helper.rb
CHANGED
@@ -47,3 +47,11 @@ def change_schema
|
|
47
47
|
end
|
48
48
|
ActiveRecord::Migration.verbose = true
|
49
49
|
end
|
50
|
+
|
51
|
+
def remove_object_changes_column
|
52
|
+
ActiveRecord::Migration.verbose = false
|
53
|
+
ActiveRecord::Schema.define do
|
54
|
+
remove_column :versions, :object_changes
|
55
|
+
end
|
56
|
+
ActiveRecord::Migration.verbose = true
|
57
|
+
end
|
data/test/unit/model_test.rb
CHANGED
@@ -60,6 +60,9 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
60
60
|
assert @widget.live?
|
61
61
|
end
|
62
62
|
|
63
|
+
should 'should not have changes' do
|
64
|
+
assert_nil @widget.versions.last.changeset
|
65
|
+
end
|
63
66
|
|
64
67
|
context 'and then updated without any changes' do
|
65
68
|
setup { @widget.save }
|
@@ -97,6 +100,17 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
97
100
|
assert @widget.versions.map(&:reify).compact.all? { |w| !w.live? }
|
98
101
|
end
|
99
102
|
|
103
|
+
should 'have stored changes' do
|
104
|
+
assert_equal ({'name' => ['Henry', 'Harry']}), YAML::load(@widget.versions.last.object_changes)
|
105
|
+
assert_equal ({'name' => ['Henry', 'Harry']}), @widget.versions.last.changeset
|
106
|
+
end
|
107
|
+
|
108
|
+
should 'not have stored changes if object_changes column doesn\'t exist' do
|
109
|
+
remove_object_changes_column
|
110
|
+
Version.reset_column_information
|
111
|
+
assert_nil @widget.versions.last.changeset
|
112
|
+
end
|
113
|
+
|
100
114
|
if defined?(ActiveRecord::IdentityMap) && ActiveRecord::IdentityMap.respond_to?(:without)
|
101
115
|
should 'not clobber the IdentityMap when reifying' do
|
102
116
|
module ActiveRecord::IdentityMap
|
@@ -118,7 +132,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
118
132
|
setup do
|
119
133
|
@wotsit = @widget.create_wotsit :name => 'John'
|
120
134
|
end
|
121
|
-
|
135
|
+
|
122
136
|
should 'not copy the has_one association by default when reifying' do
|
123
137
|
reified_widget = @widget.versions.last.reify
|
124
138
|
assert_equal @wotsit, reified_widget.wotsit # association hasn't been affected by reifying
|
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: 9
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 2.2.
|
9
|
+
- 7
|
10
|
+
version: 2.2.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andy Stewart
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-07-
|
18
|
+
date: 2011-07-13 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -109,6 +109,7 @@ files:
|
|
109
109
|
- Rakefile
|
110
110
|
- lib/generators/paper_trail/USAGE
|
111
111
|
- lib/generators/paper_trail/install_generator.rb
|
112
|
+
- lib/generators/paper_trail/templates/add_object_changes_column_to_versions.rb
|
112
113
|
- lib/generators/paper_trail/templates/create_versions.rb
|
113
114
|
- lib/paper_trail.rb
|
114
115
|
- lib/paper_trail/config.rb
|