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 CHANGED
@@ -7,3 +7,4 @@ pkg/*
7
7
  *.gem
8
8
  .bundle
9
9
  Gemfile.lock
10
+ vendor/*
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
- When you're storing every version of an object, as PaperTrail lets you do, you're almost certainly going to want to diff those versions against each other. However I haven't built a diff method into PaperTrail because I think diffing is best left to dedicated libraries, and also it's hard to come up with a diff method to suit all the use cases.
456
+ There are two scenarios: diffing adjacent versions and diffing non-adjacent versions.
457
457
 
458
- You might be surprised that PaperTrail doesn't use diffs internally anyway. 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.
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
- So instead here are some specialised diffing libraries which you can use on top of PaperTrail.
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
@@ -0,0 +1,9 @@
1
+ class AddObjectChangesColumnToVersions < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :versions, :object_changes, :text
4
+ end
5
+
6
+ def self.down
7
+ remove_column :versions, :object_changes
8
+ end
9
+ end
@@ -109,9 +109,13 @@ module PaperTrail
109
109
 
110
110
  def record_update
111
111
  if switched_on? && changed_notably?
112
- versions.build merge_metadata(:event => 'update',
113
- :object => object_to_string(item_before_change),
114
- :whodunnit => PaperTrail.whodunnit)
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
 
@@ -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
@@ -1,3 +1,3 @@
1
1
  module PaperTrail
2
- VERSION = '2.2.6'
2
+ VERSION = '2.2.7'
3
3
  end
@@ -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
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
@@ -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: 11
4
+ hash: 9
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
8
  - 2
9
- - 6
10
- version: 2.2.6
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-11 00:00:00 +01:00
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