paper_trail 2.6.4 → 2.7.0
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/.travis.yml +2 -2
- data/CHANGELOG.md +8 -0
- data/README.md +21 -1
- data/lib/paper_trail.rb +4 -0
- data/lib/paper_trail/config.rb +4 -4
- data/lib/paper_trail/has_paper_trail.rb +53 -8
- data/lib/paper_trail/serializers/yaml.rb +15 -0
- data/lib/paper_trail/version.rb +5 -2
- data/lib/paper_trail/version_number.rb +1 -1
- data/test/dummy/app/models/person.rb +23 -0
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +1 -0
- data/test/unit/model_test.rb +87 -3
- data/test/unit/serializer_test.rb +71 -0
- metadata +5 -2
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 2.7.0
|
2
|
+
|
3
|
+
- [#164](https://github.com/airblade/paper_trail/pull/164) - Allow for custom serializer for storage of object attributes.
|
4
|
+
- [#180](https://github.com/airblade/paper_trail/pull/180) - Store serialized representation of serialized attributes
|
5
|
+
on the `object_changes` column in the `Version` table.
|
6
|
+
- [#183](https://github.com/airblade/paper_trail/pull/183) - Fully qualify the `Version` class to help prevent
|
7
|
+
namespace resolution errors within other gems / plugins.
|
8
|
+
|
1
9
|
## 2.6.4
|
2
10
|
|
3
11
|
- [#181](https://github.com/airblade/paper_trail/issues/181)/[#182](https://github.com/airblade/paper_trail/pull/182) -
|
data/README.md
CHANGED
@@ -572,7 +572,7 @@ You can store arbitrary model-level metadata alongside each version like this:
|
|
572
572
|
```ruby
|
573
573
|
class Article < ActiveRecord::Base
|
574
574
|
belongs_to :author
|
575
|
-
has_paper_trail :meta => { :author_id =>
|
575
|
+
has_paper_trail :meta => { :author_id => :author_id,
|
576
576
|
:word_count => :count_words,
|
577
577
|
:answer => 42 }
|
578
578
|
def count_words
|
@@ -741,6 +741,16 @@ Or a block:
|
|
741
741
|
end
|
742
742
|
```
|
743
743
|
|
744
|
+
## Using a custom serializer
|
745
|
+
|
746
|
+
By default, PaperTrail stores your changes as a YAML dump. You can override this with the serializer config option:
|
747
|
+
|
748
|
+
```ruby
|
749
|
+
>> PaperTrail.serializer = MyCustomSerializer
|
750
|
+
```
|
751
|
+
|
752
|
+
The serializer needs to be a class that responds to a `load` and `dump` method.
|
753
|
+
|
744
754
|
## Deleting Old Versions
|
745
755
|
|
746
756
|
Over time your `versions` table will grow to an unwieldy size. Because each version is self-contained (see the Diffing section above for more) you can simply delete any records you don't want any more. For example:
|
@@ -840,6 +850,16 @@ Many thanks to:
|
|
840
850
|
* [Ben Woosley](https://github.com/Empact)
|
841
851
|
* [Philip Arndt](https://github.com/parndt)
|
842
852
|
* [Daniel Vydra](https://github.com/dvydra)
|
853
|
+
* [Byron Bowerman](https://github.com/BM5k)
|
854
|
+
* [Nicolas Buduroi](https://github.com/budu)
|
855
|
+
* [Pikender Sharma](https://github.com/pikender)
|
856
|
+
* [Paul Brannan](https://github.com/cout)
|
857
|
+
* [Ben Morrall](https://github.com/bmorrall)
|
858
|
+
* [Yves Senn](https://github.com/senny)
|
859
|
+
* [Ben Atkins](https://github.com/fullbridge-batkins)
|
860
|
+
* [Yves Senn](https://github.com/senny)
|
861
|
+
* [Tyler Rick](https://github.com/TylerRick)
|
862
|
+
* [Bradley Priest](https://github.com/bradleypriest)
|
843
863
|
|
844
864
|
|
845
865
|
## Inspirations
|
data/lib/paper_trail.rb
CHANGED
@@ -4,6 +4,7 @@ require 'paper_trail/config'
|
|
4
4
|
require 'paper_trail/controller'
|
5
5
|
require 'paper_trail/has_paper_trail'
|
6
6
|
require 'paper_trail/version'
|
7
|
+
require 'paper_trail/serializers/yaml'
|
7
8
|
|
8
9
|
# PaperTrail's module methods can be called in both models and controllers.
|
9
10
|
module PaperTrail
|
@@ -68,6 +69,9 @@ module PaperTrail
|
|
68
69
|
paper_trail_store[:controller_info] = value
|
69
70
|
end
|
70
71
|
|
72
|
+
def self.serializer
|
73
|
+
PaperTrail.config.serializer
|
74
|
+
end
|
71
75
|
|
72
76
|
private
|
73
77
|
|
data/lib/paper_trail/config.rb
CHANGED
@@ -3,12 +3,12 @@ require 'singleton'
|
|
3
3
|
module PaperTrail
|
4
4
|
class Config
|
5
5
|
include Singleton
|
6
|
-
attr_accessor :enabled, :timestamp_field
|
7
|
-
|
6
|
+
attr_accessor :enabled, :timestamp_field, :serializer
|
7
|
+
|
8
8
|
def initialize
|
9
|
-
# Indicates whether PaperTrail is on or off.
|
10
|
-
@enabled = true
|
9
|
+
@enabled = true # Indicates whether PaperTrail is on or off.
|
11
10
|
@timestamp_field = :created_at
|
11
|
+
@serializer = PaperTrail::Serializers::Yaml
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -39,7 +39,7 @@ module PaperTrail
|
|
39
39
|
attr_accessor self.version_association_name
|
40
40
|
|
41
41
|
class_attribute :version_class_name
|
42
|
-
self.version_class_name = options[:class_name] || 'Version'
|
42
|
+
self.version_class_name = options[:class_name] || '::Version'
|
43
43
|
|
44
44
|
class_attribute :paper_trail_options
|
45
45
|
self.paper_trail_options = options.dup
|
@@ -80,6 +80,44 @@ module PaperTrail
|
|
80
80
|
def paper_trail_on
|
81
81
|
self.paper_trail_enabled_for_model = true
|
82
82
|
end
|
83
|
+
|
84
|
+
# Used for Version#object attribute
|
85
|
+
def serialize_attributes(attributes)
|
86
|
+
serialized_attributes.each do |key, coder|
|
87
|
+
if attributes.key?(key)
|
88
|
+
attributes[key] = coder.dump(attributes[key])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def unserialize_attributes(attributes)
|
94
|
+
serialized_attributes.each do |key, coder|
|
95
|
+
if attributes.key?(key)
|
96
|
+
attributes[key] = coder.load(attributes[key])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Used for Version#object_changes attribute
|
102
|
+
def serialize_attribute_changes(changes)
|
103
|
+
serialized_attributes.each do |key, coder|
|
104
|
+
if changes.key?(key)
|
105
|
+
old_value, new_value = changes[key]
|
106
|
+
changes[key] = [coder.dump(old_value),
|
107
|
+
coder.dump(new_value)]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def unserialize_attribute_changes(changes)
|
113
|
+
serialized_attributes.each do |key, coder|
|
114
|
+
if changes.key?(key)
|
115
|
+
old_value, new_value = changes[key]
|
116
|
+
changes[key] = [coder.load(old_value),
|
117
|
+
coder.load(new_value)]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
83
121
|
end
|
84
122
|
|
85
123
|
# Wrap the following methods in a module so we can include them only in the
|
@@ -151,8 +189,7 @@ module PaperTrail
|
|
151
189
|
}
|
152
190
|
|
153
191
|
if changed_notably? and version_class.column_names.include?('object_changes')
|
154
|
-
|
155
|
-
data[:object_changes] = self.changes.reject { |k, _| !notably_changed.include?(k) }.to_yaml
|
192
|
+
data[:object_changes] = changes_for_paper_trail.to_yaml
|
156
193
|
end
|
157
194
|
|
158
195
|
send(self.class.versions_association_name).create merge_metadata(data)
|
@@ -167,15 +204,20 @@ module PaperTrail
|
|
167
204
|
:whodunnit => PaperTrail.whodunnit
|
168
205
|
}
|
169
206
|
if version_class.column_names.include? 'object_changes'
|
170
|
-
|
171
|
-
data[:object_changes] = self.changes.reject do |key, value|
|
172
|
-
!notably_changed.include?(key)
|
173
|
-
end.to_yaml
|
207
|
+
data[:object_changes] = PaperTrail.serializer.dump(changes_for_paper_trail)
|
174
208
|
end
|
175
209
|
send(self.class.versions_association_name).build merge_metadata(data)
|
176
210
|
end
|
177
211
|
end
|
178
212
|
|
213
|
+
def changes_for_paper_trail
|
214
|
+
self.changes.keep_if do |key, value|
|
215
|
+
notably_changed.include?(key)
|
216
|
+
end.tap do |changes|
|
217
|
+
self.class.serialize_attribute_changes(changes) # Use serialized value for attributes when necessary
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
179
221
|
def record_destroy
|
180
222
|
if switched_on? and not new_record?
|
181
223
|
version_class.create merge_metadata(:item_id => self.id,
|
@@ -221,7 +263,10 @@ module PaperTrail
|
|
221
263
|
end
|
222
264
|
|
223
265
|
def object_to_string(object)
|
224
|
-
object.attributes.except(*self.class.paper_trail_options[:skip]).
|
266
|
+
_attrs = object.attributes.except(*self.class.paper_trail_options[:skip]).tap do |attributes|
|
267
|
+
self.class.serialize_attributes attributes
|
268
|
+
end
|
269
|
+
PaperTrail.serializer.dump(_attrs)
|
225
270
|
end
|
226
271
|
|
227
272
|
def changed_notably?
|
data/lib/paper_trail/version.rb
CHANGED
@@ -55,7 +55,7 @@ class Version < ActiveRecord::Base
|
|
55
55
|
options.reverse_merge! :has_one => false
|
56
56
|
|
57
57
|
unless object.nil?
|
58
|
-
attrs =
|
58
|
+
attrs = PaperTrail.serializer.load object
|
59
59
|
|
60
60
|
# Normally a polymorphic belongs_to relationship allows us
|
61
61
|
# to get the object we belong to by calling, in this case,
|
@@ -79,6 +79,7 @@ class Version < ActiveRecord::Base
|
|
79
79
|
model = klass.new
|
80
80
|
end
|
81
81
|
|
82
|
+
model.class.unserialize_attributes attrs
|
82
83
|
attrs.each do |k, v|
|
83
84
|
if model.respond_to?("#{k}=")
|
84
85
|
model.send :write_attribute, k.to_sym, v
|
@@ -103,7 +104,9 @@ class Version < ActiveRecord::Base
|
|
103
104
|
def changeset
|
104
105
|
if self.class.column_names.include? 'object_changes'
|
105
106
|
if changes = object_changes
|
106
|
-
HashWithIndifferentAccess[
|
107
|
+
HashWithIndifferentAccess[PaperTrail.serializer.load(changes)].tap do |changes|
|
108
|
+
item_type.constantize.unserialize_attribute_changes(changes)
|
109
|
+
end
|
107
110
|
else
|
108
111
|
{}
|
109
112
|
end
|
@@ -2,4 +2,27 @@ class Person < ActiveRecord::Base
|
|
2
2
|
has_many :authorships, :dependent => :destroy
|
3
3
|
has_many :books, :through => :authorships
|
4
4
|
has_paper_trail
|
5
|
+
|
6
|
+
# Convert strings to TimeZone objects when assigned
|
7
|
+
def time_zone=(value)
|
8
|
+
if value.is_a? ActiveSupport::TimeZone
|
9
|
+
super
|
10
|
+
else
|
11
|
+
zone = ::Time.find_zone(value) # nil if can't find time zone
|
12
|
+
super zone
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Store TimeZone objects as strings when serialized to database
|
17
|
+
class TimeZoneSerializer
|
18
|
+
def dump(zone)
|
19
|
+
zone.try(:name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def load(value)
|
23
|
+
::Time.find_zone!(value) rescue nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
serialize :time_zone, TimeZoneSerializer.new
|
5
28
|
end
|
data/test/unit/model_test.rb
CHANGED
@@ -49,11 +49,11 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
49
49
|
end
|
50
50
|
|
51
51
|
should 'have removed the skipped attributes when saving the previous version' do
|
52
|
-
assert_equal nil,
|
52
|
+
assert_equal nil, PaperTrail.serializer.load(@old_article.object)['file_upload']
|
53
53
|
end
|
54
54
|
|
55
55
|
should 'have kept the non-skipped attributes in the previous version' do
|
56
|
-
assert_equal 'Some text here.',
|
56
|
+
assert_equal 'Some text here.', PaperTrail.serializer.load(@old_article.object)['content']
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -201,7 +201,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
201
201
|
end
|
202
202
|
|
203
203
|
should 'have stored changes' do
|
204
|
-
assert_equal ({'name' => ['Henry', 'Harry']}),
|
204
|
+
assert_equal ({'name' => ['Henry', 'Harry']}), PaperTrail.serializer.load(@widget.versions.last.object_changes)
|
205
205
|
assert_equal ({'name' => ['Henry', 'Harry']}), @widget.versions.last.changeset
|
206
206
|
end
|
207
207
|
|
@@ -916,6 +916,90 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
916
916
|
end
|
917
917
|
end
|
918
918
|
|
919
|
+
context 'When an attribute has a custom serializer' do
|
920
|
+
setup { @person = Person.new(:time_zone => "Samoa") }
|
921
|
+
|
922
|
+
should "be an instance of ActiveSupport::TimeZone" do
|
923
|
+
assert_equal ActiveSupport::TimeZone, @person.time_zone.class
|
924
|
+
end
|
925
|
+
|
926
|
+
context 'when the model is saved' do
|
927
|
+
setup do
|
928
|
+
@changes_before_save = @person.changes.dup
|
929
|
+
@person.save!
|
930
|
+
end
|
931
|
+
|
932
|
+
# Test for serialization:
|
933
|
+
should 'version.object_changes should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
|
934
|
+
assert @person.versions.last.object_changes.length < 105, "object_changes length was #{@person.versions.last.object_changes.length}"
|
935
|
+
end
|
936
|
+
# It should store the serialized value.
|
937
|
+
should 'version.object_changes attribute should have stored the value returned by the attribute serializer' do
|
938
|
+
as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object_changes)]
|
939
|
+
assert_equal [nil, 'Samoa'], as_stored_in_version[:time_zone]
|
940
|
+
assert_equal @person.instance_variable_get(:@attributes)['time_zone'].serialized_value, as_stored_in_version[:time_zone].last
|
941
|
+
end
|
942
|
+
|
943
|
+
# Tests for unserialization:
|
944
|
+
should 'version.changeset should convert the attribute value back to its original, unserialized value' do
|
945
|
+
assert_equal @person.instance_variable_get(:@attributes)['time_zone'].unserialized_value, @person.versions.last.changeset[:time_zone].last
|
946
|
+
end
|
947
|
+
should "record.changes (before save) returns the original, unserialized values" do
|
948
|
+
assert_equal [NilClass, ActiveSupport::TimeZone], @changes_before_save[:time_zone].map(&:class)
|
949
|
+
end
|
950
|
+
should 'version.changeset should be the same as record.changes was before the save' do
|
951
|
+
assert_equal @changes_before_save, @person.versions.last.changeset.delete_if { |key, val| key.to_sym == :id }
|
952
|
+
assert_equal [NilClass, ActiveSupport::TimeZone], @person.versions.last.changeset[:time_zone].map(&:class)
|
953
|
+
end
|
954
|
+
|
955
|
+
context 'when that attribute is updated' do
|
956
|
+
setup do
|
957
|
+
@attribute_value_before_change = @person.instance_variable_get(:@attributes)['time_zone']
|
958
|
+
@person.assign_attributes({ :time_zone => 'Pacific Time (US & Canada)' })
|
959
|
+
@changes_before_save = @person.changes.dup
|
960
|
+
@person.save!
|
961
|
+
end
|
962
|
+
|
963
|
+
# Tests for serialization:
|
964
|
+
# Before the serialized attributes fix, the object/object_changes value that was stored was ridiculously long (58723).
|
965
|
+
should 'version.object should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
|
966
|
+
assert @person.versions.last.object. length < 105, "object length was #{@person.versions.last.object .length}"
|
967
|
+
end
|
968
|
+
should 'version.object_changes should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
|
969
|
+
assert @person.versions.last.object_changes.length < 105, "object_changes length was #{@person.versions.last.object_changes.length}"
|
970
|
+
end
|
971
|
+
# But now it stores the short, serialized value.
|
972
|
+
should 'version.object attribute should have stored the value returned by the attribute serializer' do
|
973
|
+
as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object)]
|
974
|
+
assert_equal 'Samoa', as_stored_in_version[:time_zone]
|
975
|
+
assert_equal @attribute_value_before_change.serialized_value, as_stored_in_version[:time_zone]
|
976
|
+
end
|
977
|
+
should 'version.object_changes attribute should have stored the value returned by the attribute serializer' do
|
978
|
+
as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object_changes)]
|
979
|
+
assert_equal ['Samoa', 'Pacific Time (US & Canada)'], as_stored_in_version[:time_zone]
|
980
|
+
assert_equal @person.instance_variable_get(:@attributes)['time_zone'].serialized_value, as_stored_in_version[:time_zone].last
|
981
|
+
end
|
982
|
+
|
983
|
+
# Tests for unserialization:
|
984
|
+
should 'version.reify should convert the attribute value back to its original, unserialized value' do
|
985
|
+
assert_equal @attribute_value_before_change.unserialized_value, @person.versions.last.reify.time_zone
|
986
|
+
end
|
987
|
+
should 'version.changeset should convert the attribute value back to its original, unserialized value' do
|
988
|
+
assert_equal @person.instance_variable_get(:@attributes)['time_zone'].unserialized_value, @person.versions.last.changeset[:time_zone].last
|
989
|
+
end
|
990
|
+
should "record.changes (before save) returns the original, unserialized values" do
|
991
|
+
assert_equal [ActiveSupport::TimeZone, ActiveSupport::TimeZone], @changes_before_save[:time_zone].map(&:class)
|
992
|
+
end
|
993
|
+
should 'version.changeset should be the same as record.changes was before the save' do
|
994
|
+
assert_equal @changes_before_save, @person.versions.last.changeset
|
995
|
+
assert_equal [ActiveSupport::TimeZone, ActiveSupport::TimeZone], @person.versions.last.changeset[:time_zone].map(&:class)
|
996
|
+
end
|
997
|
+
|
998
|
+
end
|
999
|
+
end
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
|
919
1003
|
context 'A new model instance which uses a custom Version class' do
|
920
1004
|
setup { @post = Post.new }
|
921
1005
|
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CustomSerializer
|
4
|
+
require 'json'
|
5
|
+
def self.dump(object_hash)
|
6
|
+
JSON.dump object_hash
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.load(string)
|
10
|
+
JSON.parse string
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class SerializerTest < ActiveSupport::TestCase
|
15
|
+
|
16
|
+
context 'YAML Serializer' do
|
17
|
+
setup do
|
18
|
+
Fluxor.instance_eval <<-END
|
19
|
+
has_paper_trail
|
20
|
+
END
|
21
|
+
|
22
|
+
@fluxor = Fluxor.create :name => 'Some text.'
|
23
|
+
@fluxor.update_attributes :name => 'Some more text.'
|
24
|
+
end
|
25
|
+
|
26
|
+
should 'work with the default yaml serializer' do
|
27
|
+
# Normal behaviour
|
28
|
+
assert_equal 2, @fluxor.versions.length
|
29
|
+
assert_nil @fluxor.versions[0].reify
|
30
|
+
assert_equal 'Some text.', @fluxor.versions[1].reify.name
|
31
|
+
|
32
|
+
|
33
|
+
# Check values are stored as YAML.
|
34
|
+
hash = {"widget_id" => nil,"name" =>"Some text.","id" =>1}
|
35
|
+
assert_equal YAML.dump(hash), @fluxor.versions[1].object
|
36
|
+
assert_equal hash, YAML.load(@fluxor.versions[1].object)
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'Custom Serializer' do
|
42
|
+
setup do
|
43
|
+
PaperTrail.config.serializer = CustomSerializer
|
44
|
+
|
45
|
+
Fluxor.instance_eval <<-END
|
46
|
+
has_paper_trail
|
47
|
+
END
|
48
|
+
|
49
|
+
@fluxor = Fluxor.create :name => 'Some text.'
|
50
|
+
@fluxor.update_attributes :name => 'Some more text.'
|
51
|
+
end
|
52
|
+
|
53
|
+
teardown do
|
54
|
+
PaperTrail.config.serializer = PaperTrail::Serializers::Yaml
|
55
|
+
end
|
56
|
+
|
57
|
+
should 'work with custom serializer' do
|
58
|
+
# Normal behaviour
|
59
|
+
assert_equal 2, @fluxor.versions.length
|
60
|
+
assert_nil @fluxor.versions[0].reify
|
61
|
+
assert_equal 'Some text.', @fluxor.versions[1].reify.name
|
62
|
+
|
63
|
+
# Check values are stored as JSON.
|
64
|
+
hash = {"widget_id" => nil,"name" =>"Some text.","id" =>1}
|
65
|
+
assert_equal JSON.dump(hash), @fluxor.versions[1].object
|
66
|
+
assert_equal hash, JSON.parse(@fluxor.versions[1].object)
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
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: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
@@ -128,6 +128,7 @@ files:
|
|
128
128
|
- lib/paper_trail/config.rb
|
129
129
|
- lib/paper_trail/controller.rb
|
130
130
|
- lib/paper_trail/has_paper_trail.rb
|
131
|
+
- lib/paper_trail/serializers/yaml.rb
|
131
132
|
- lib/paper_trail/version.rb
|
132
133
|
- lib/paper_trail/version_number.rb
|
133
134
|
- paper_trail.gemspec
|
@@ -192,6 +193,7 @@ files:
|
|
192
193
|
- test/test_helper.rb
|
193
194
|
- test/unit/inheritance_column_test.rb
|
194
195
|
- test/unit/model_test.rb
|
196
|
+
- test/unit/serializer_test.rb
|
195
197
|
- test/unit/timestamp_test.rb
|
196
198
|
- test/unit/version_test.rb
|
197
199
|
homepage: http://github.com/airblade/paper_trail
|
@@ -280,5 +282,6 @@ test_files:
|
|
280
282
|
- test/test_helper.rb
|
281
283
|
- test/unit/inheritance_column_test.rb
|
282
284
|
- test/unit/model_test.rb
|
285
|
+
- test/unit/serializer_test.rb
|
283
286
|
- test/unit/timestamp_test.rb
|
284
287
|
- test/unit/version_test.rb
|