paper_trail 2.2.3 → 2.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -0
- data/lib/paper_trail/has_paper_trail.rb +8 -3
- data/lib/paper_trail/version.rb +49 -37
- data/lib/paper_trail/version_number.rb +1 -1
- data/test/unit/model_test.rb +16 -0
- metadata +4 -4
data/README.md
CHANGED
@@ -143,9 +143,14 @@ module PaperTrail
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def item_before_change
|
146
|
-
self.dup
|
147
|
-
|
148
|
-
|
146
|
+
previous = self.dup
|
147
|
+
# `dup` clears timestamps so we add them back.
|
148
|
+
all_timestamp_attributes.each do |column|
|
149
|
+
previous[column] = send(column) if respond_to?(column) && !send(column).nil?
|
150
|
+
end
|
151
|
+
previous.tap do |prev|
|
152
|
+
prev.id = id
|
153
|
+
changed_attributes.each { |attr, before| prev[attr] = before }
|
149
154
|
end
|
150
155
|
end
|
151
156
|
|
data/lib/paper_trail/version.rb
CHANGED
@@ -31,48 +31,50 @@ class Version < ActiveRecord::Base
|
|
31
31
|
# set to a float to change the lookback time (check whether your db supports
|
32
32
|
# sub-second datetimes if you want them).
|
33
33
|
def reify(options = {})
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
34
|
+
without_identity_map do
|
35
|
+
options.reverse_merge! :has_one => 3
|
36
|
+
|
37
|
+
unless object.nil?
|
38
|
+
attrs = YAML::load object
|
39
|
+
|
40
|
+
# Normally a polymorphic belongs_to relationship allows us
|
41
|
+
# to get the object we belong to by calling, in this case,
|
42
|
+
# +item+. However this returns nil if +item+ has been
|
43
|
+
# destroyed, and we need to be able to retrieve destroyed
|
44
|
+
# objects.
|
45
|
+
#
|
46
|
+
# In this situation we constantize the +item_type+ to get hold of
|
47
|
+
# the class...except when the stored object's attributes
|
48
|
+
# include a +type+ key. If this is the case, the object
|
49
|
+
# we belong to is using single table inheritance and the
|
50
|
+
# +item_type+ will be the base class, not the actual subclass.
|
51
|
+
# If +type+ is present but empty, the class is the base class.
|
52
|
+
|
53
|
+
if item
|
54
|
+
model = item
|
55
|
+
else
|
56
|
+
inheritance_column_name = item_type.constantize.inheritance_column
|
57
|
+
class_name = attrs[inheritance_column_name].blank? ? item_type : attrs[inheritance_column_name]
|
58
|
+
klass = class_name.constantize
|
59
|
+
model = klass.new
|
60
|
+
end
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
attrs.each do |k, v|
|
63
|
+
begin
|
64
|
+
model.send :write_attribute, k.to_sym , v
|
65
|
+
rescue NoMethodError
|
66
|
+
logger.warn "Attribute #{k} does not exist on #{item_type} (Version id: #{id})."
|
67
|
+
end
|
66
68
|
end
|
67
|
-
end
|
68
69
|
|
69
|
-
|
70
|
+
model.version = self
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
72
|
+
unless options[:has_one] == false
|
73
|
+
reify_has_ones model, options[:has_one]
|
74
|
+
end
|
74
75
|
|
75
|
-
|
76
|
+
model
|
77
|
+
end
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
@@ -105,6 +107,16 @@ class Version < ActiveRecord::Base
|
|
105
107
|
|
106
108
|
private
|
107
109
|
|
110
|
+
# In Rails 3.1+, calling reify on a previous version confuses the
|
111
|
+
# IdentityMap, if enabled. This prevents insertion into the map.
|
112
|
+
def without_identity_map(&block)
|
113
|
+
if defined?(ActiveRecord::IdentityMap) && ActiveRecord::IdentityMap.respond_to?(:without)
|
114
|
+
ActiveRecord::IdentityMap.without(&block)
|
115
|
+
else
|
116
|
+
block.call
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
108
120
|
# Restore the `model`'s has_one associations as they were when this version was
|
109
121
|
# superseded by the next (because that's what the user was looking at when they
|
110
122
|
# made the change).
|
data/test/unit/model_test.rb
CHANGED
@@ -97,6 +97,22 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
97
97
|
assert @widget.versions.map(&:reify).compact.all? { |w| !w.live? }
|
98
98
|
end
|
99
99
|
|
100
|
+
if defined?(ActiveRecord::IdentityMap) && ActiveRecord::IdentityMap.respond_to?(:without)
|
101
|
+
should 'not clobber the IdentityMap when reifying' do
|
102
|
+
module ActiveRecord::IdentityMap
|
103
|
+
class << self
|
104
|
+
alias :__without :without
|
105
|
+
def without(&block)
|
106
|
+
@unclobbered = true
|
107
|
+
__without(&block)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
@widget.versions.last.reify
|
113
|
+
assert ActiveRecord::IdentityMap.instance_variable_get("@unclobbered")
|
114
|
+
end
|
115
|
+
end
|
100
116
|
|
101
117
|
context 'and has one associated object' do
|
102
118
|
setup do
|
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: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 2.2.
|
9
|
+
- 4
|
10
|
+
version: 2.2.4
|
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-05-
|
18
|
+
date: 2011-05-16 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|