paper_trail 2.2.8 → 2.2.9
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 +12 -0
- data/lib/paper_trail/has_paper_trail.rb +14 -7
- data/lib/paper_trail/version.rb +1 -1
- data/lib/paper_trail/version_number.rb +1 -1
- data/test/dummy/app/models/document.rb +3 -0
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +5 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/test_helper.rb +0 -8
- data/test/unit/model_test.rb +23 -6
- metadata +6 -4
data/README.md
CHANGED
@@ -23,6 +23,7 @@ There's an excellent [Railscast on implementing Undo with Paper Trail](http://ra
|
|
23
23
|
* No configuration necessary.
|
24
24
|
* Stores everything in a single database table by default (generates migration for you), or can use separate tables for separate models.
|
25
25
|
* Supports custom version classes so different models' versions can have different behaviour.
|
26
|
+
* Supports custom name for versions association.
|
26
27
|
* Thoroughly tested.
|
27
28
|
* Threadsafe.
|
28
29
|
|
@@ -327,6 +328,17 @@ This allows you to store each model's versions in a separate table, which is use
|
|
327
328
|
|
328
329
|
Alternatively you could store certain metadata for one type of version, and other metadata for other versions.
|
329
330
|
|
331
|
+
You can also specify a custom name for the versions association. This is useful if you already have a `versions` method on your model. For example:
|
332
|
+
|
333
|
+
class Post < ActiveRecord::Base
|
334
|
+
has_paper_trail :versions_association_name => :paper_trail_versions
|
335
|
+
|
336
|
+
# Existing versions method. We don't want to clash.
|
337
|
+
def versions
|
338
|
+
...
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
330
342
|
|
331
343
|
## Associations
|
332
344
|
|
@@ -18,6 +18,7 @@ module PaperTrail
|
|
18
18
|
# Values are objects or procs (which are called with `self`, i.e. the model with the paper
|
19
19
|
# trail). See `PaperTrail::Controller.info_for_paper_trail` for how to store data from
|
20
20
|
# the controller.
|
21
|
+
# :versions_association_name the name to use for the versions association. Default is `:versions`.
|
21
22
|
def has_paper_trail(options = {})
|
22
23
|
# Lazily include the instance methods so we don't clutter up
|
23
24
|
# any more ActiveRecord models than we have to.
|
@@ -41,7 +42,13 @@ module PaperTrail
|
|
41
42
|
cattr_accessor :paper_trail_enabled_for_model
|
42
43
|
self.paper_trail_enabled_for_model = true
|
43
44
|
|
44
|
-
|
45
|
+
cattr_accessor :versions_association_name
|
46
|
+
self.versions_association_name = options[:versions] || :versions
|
47
|
+
|
48
|
+
has_many self.versions_association_name,
|
49
|
+
:class_name => version_class_name,
|
50
|
+
:as => :item,
|
51
|
+
:order => "created_at ASC, #{self.primary_key} ASC"
|
45
52
|
|
46
53
|
after_create :record_create
|
47
54
|
before_update :record_update
|
@@ -77,13 +84,13 @@ module PaperTrail
|
|
77
84
|
def version_at(timestamp, reify_options={})
|
78
85
|
# Because a version stores how its object looked *before* the change,
|
79
86
|
# we need to look for the first version created *after* the timestamp.
|
80
|
-
version =
|
87
|
+
version = send(self.class.versions_association_name).after(timestamp).first
|
81
88
|
version ? version.reify(reify_options) : self
|
82
89
|
end
|
83
90
|
|
84
91
|
# Returns the object (not a Version) as it was most recently.
|
85
92
|
def previous_version
|
86
|
-
preceding_version = version ? version.previous :
|
93
|
+
preceding_version = version ? version.previous : send(self.class.versions_association_name).last
|
87
94
|
preceding_version.try :reify
|
88
95
|
end
|
89
96
|
|
@@ -103,7 +110,7 @@ module PaperTrail
|
|
103
110
|
|
104
111
|
def record_create
|
105
112
|
if switched_on?
|
106
|
-
|
113
|
+
send(self.class.versions_association_name).create merge_metadata(:event => 'create', :whodunnit => PaperTrail.whodunnit)
|
107
114
|
end
|
108
115
|
end
|
109
116
|
|
@@ -114,13 +121,13 @@ module PaperTrail
|
|
114
121
|
:object => object_to_string(item_before_change),
|
115
122
|
:whodunnit => PaperTrail.whodunnit
|
116
123
|
}
|
117
|
-
if
|
124
|
+
if version_class.column_names.include? 'object_changes'
|
118
125
|
# The double negative (reject, !include?) preserves the hash structure of self.changes.
|
119
126
|
data[:object_changes] = self.changes.reject do |key, value|
|
120
127
|
!notably_changed.include?(key)
|
121
128
|
end.to_yaml
|
122
129
|
end
|
123
|
-
|
130
|
+
send(self.class.versions_association_name).build merge_metadata(data)
|
124
131
|
end
|
125
132
|
end
|
126
133
|
|
@@ -132,7 +139,7 @@ module PaperTrail
|
|
132
139
|
:object => object_to_string(item_before_change),
|
133
140
|
:whodunnit => PaperTrail.whodunnit)
|
134
141
|
end
|
135
|
-
|
142
|
+
send(self.class.versions_association_name).send :load_target
|
136
143
|
end
|
137
144
|
|
138
145
|
def merge_metadata(data)
|
data/lib/paper_trail/version.rb
CHANGED
@@ -82,7 +82,7 @@ class Version < ActiveRecord::Base
|
|
82
82
|
# Returns what changed in this version of the item. Cf. `ActiveModel::Dirty#changes`.
|
83
83
|
# Returns nil if your `versions` table does not have an `object_changes` text column.
|
84
84
|
def changeset
|
85
|
-
if
|
85
|
+
if self.class.column_names.include? 'object_changes'
|
86
86
|
if changes = object_changes
|
87
87
|
YAML::load(changes)
|
88
88
|
else
|
@@ -93,6 +93,10 @@ class SetUpTestTables < ActiveRecord::Migration
|
|
93
93
|
t.string :name
|
94
94
|
t.string :species # single table inheritance column
|
95
95
|
end
|
96
|
+
|
97
|
+
create_table :documents, :force => true do |t|
|
98
|
+
t.string :name
|
99
|
+
end
|
96
100
|
end
|
97
101
|
|
98
102
|
def self.down
|
@@ -110,5 +114,6 @@ class SetUpTestTables < ActiveRecord::Migration
|
|
110
114
|
remove_index :versions, :column => [:item_type, :item_id]
|
111
115
|
drop_table :versions
|
112
116
|
drop_table :widgets
|
117
|
+
drop_table :documents
|
113
118
|
end
|
114
119
|
end
|
data/test/dummy/db/test.sqlite3
CHANGED
Binary file
|
data/test/test_helper.rb
CHANGED
@@ -47,11 +47,3 @@ 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
@@ -109,12 +109,6 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
109
109
|
assert_equal ({'name' => ['Henry', 'Harry']}), @widget.versions.last.changeset
|
110
110
|
end
|
111
111
|
|
112
|
-
should "not have stored changes if object_changes column doesn't exist" do
|
113
|
-
remove_object_changes_column
|
114
|
-
Version.reset_column_information
|
115
|
-
assert_nil @widget.versions.last.changeset
|
116
|
-
end
|
117
|
-
|
118
112
|
if defined?(ActiveRecord::IdentityMap) && ActiveRecord::IdentityMap.respond_to?(:without)
|
119
113
|
should 'not clobber the IdentityMap when reifying' do
|
120
114
|
module ActiveRecord::IdentityMap
|
@@ -786,6 +780,9 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
786
780
|
setup { @post.update_attributes({ :content => "Some new content" }) }
|
787
781
|
should_change('the number of post versions') { PostVersion.count }
|
788
782
|
should_not_change('the number of versions') { Version.count }
|
783
|
+
should "not have stored changes when object_changes column doesn't exist" do
|
784
|
+
assert_nil @post.versions.last.changeset
|
785
|
+
end
|
789
786
|
end
|
790
787
|
end
|
791
788
|
|
@@ -815,6 +812,26 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
815
812
|
end
|
816
813
|
end
|
817
814
|
|
815
|
+
context 'A model with a custom association' do
|
816
|
+
setup do
|
817
|
+
@doc = Document.create
|
818
|
+
@doc.update_attributes :name => 'Doc 1'
|
819
|
+
end
|
820
|
+
|
821
|
+
should 'not respond to versions method' do
|
822
|
+
assert !@doc.respond_to?(:versions)
|
823
|
+
end
|
824
|
+
|
825
|
+
should 'create a new version record' do
|
826
|
+
assert_equal 2, @doc.paper_trail_versions.length
|
827
|
+
end
|
828
|
+
|
829
|
+
should 'respond to previous_version as normal' do
|
830
|
+
@doc.update_attributes :name => 'Doc 2'
|
831
|
+
assert_equal 3, @doc.paper_trail_versions.length
|
832
|
+
assert_equal 'Doc 1', @doc.previous_version.name
|
833
|
+
end
|
834
|
+
end
|
818
835
|
|
819
836
|
private
|
820
837
|
|
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: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 2.2.
|
9
|
+
- 9
|
10
|
+
version: 2.2.9
|
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-23 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -128,6 +128,7 @@ files:
|
|
128
128
|
- test/dummy/app/models/authorship.rb
|
129
129
|
- test/dummy/app/models/book.rb
|
130
130
|
- test/dummy/app/models/cat.rb
|
131
|
+
- test/dummy/app/models/document.rb
|
131
132
|
- test/dummy/app/models/dog.rb
|
132
133
|
- test/dummy/app/models/fluxor.rb
|
133
134
|
- test/dummy/app/models/foo_widget.rb
|
@@ -222,6 +223,7 @@ test_files:
|
|
222
223
|
- test/dummy/app/models/authorship.rb
|
223
224
|
- test/dummy/app/models/book.rb
|
224
225
|
- test/dummy/app/models/cat.rb
|
226
|
+
- test/dummy/app/models/document.rb
|
225
227
|
- test/dummy/app/models/dog.rb
|
226
228
|
- test/dummy/app/models/fluxor.rb
|
227
229
|
- test/dummy/app/models/foo_widget.rb
|