paper_trail 2.2.3 → 2.2.4

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 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