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 CHANGED
@@ -605,6 +605,7 @@ Many thanks to:
605
605
  * [Stefan Huber](https://github.com/MSNexploder)
606
606
  * [thinkcast](https://github.com/thinkcast)
607
607
  * [Dominik Sander](https://github.com/dsander)
608
+ * [Burke Libbey](https://github.com/burke)
608
609
 
609
610
 
610
611
  ## Inspirations
@@ -143,9 +143,14 @@ module PaperTrail
143
143
  end
144
144
 
145
145
  def item_before_change
146
- self.dup.tap do |previous|
147
- previous.id = id
148
- changed_attributes.each { |attr, before| previous[attr] = before }
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
 
@@ -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
- options.reverse_merge! :has_one => 3
35
-
36
- unless object.nil?
37
- attrs = YAML::load object
38
-
39
- # Normally a polymorphic belongs_to relationship allows us
40
- # to get the object we belong to by calling, in this case,
41
- # +item+. However this returns nil if +item+ has been
42
- # destroyed, and we need to be able to retrieve destroyed
43
- # objects.
44
- #
45
- # In this situation we constantize the +item_type+ to get hold of
46
- # the class...except when the stored object's attributes
47
- # include a +type+ key. If this is the case, the object
48
- # we belong to is using single table inheritance and the
49
- # +item_type+ will be the base class, not the actual subclass.
50
- # If +type+ is present but empty, the class is the base class.
51
-
52
- if item
53
- model = item
54
- else
55
- inheritance_column_name = item_type.constantize.inheritance_column
56
- class_name = attrs[inheritance_column_name].blank? ? item_type : attrs[inheritance_column_name]
57
- klass = class_name.constantize
58
- model = klass.new
59
- end
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
- attrs.each do |k, v|
62
- begin
63
- model.send :write_attribute, k.to_sym , v
64
- rescue NoMethodError
65
- logger.warn "Attribute #{k} does not exist on #{item_type} (Version id: #{id})."
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
- model.version = self
70
+ model.version = self
70
71
 
71
- unless options[:has_one] == false
72
- reify_has_ones model, options[:has_one]
73
- end
72
+ unless options[:has_one] == false
73
+ reify_has_ones model, options[:has_one]
74
+ end
74
75
 
75
- model
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).
@@ -1,3 +1,3 @@
1
1
  module PaperTrail
2
- VERSION = '2.2.3'
2
+ VERSION = '2.2.4'
3
3
  end
@@ -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: 1
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
8
  - 2
9
- - 3
10
- version: 2.2.3
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-06 00:00:00 +01:00
18
+ date: 2011-05-16 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency