paper_trail 10.3.1 → 14.0.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.
- checksums.yaml +4 -4
- data/LICENSE +20 -0
- data/lib/generators/paper_trail/install/install_generator.rb +25 -7
- data/lib/generators/paper_trail/install/templates/create_versions.rb.erb +4 -2
- data/lib/generators/paper_trail/migration_generator.rb +5 -4
- data/lib/generators/paper_trail/update_item_subtype/update_item_subtype_generator.rb +4 -2
- data/lib/paper_trail/attribute_serializers/attribute_serializer_factory.rb +24 -10
- data/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb +17 -45
- data/lib/paper_trail/compatibility.rb +3 -3
- data/lib/paper_trail/config.rb +0 -33
- data/lib/paper_trail/errors.rb +33 -0
- data/lib/paper_trail/events/base.rb +92 -69
- data/lib/paper_trail/events/destroy.rb +1 -1
- data/lib/paper_trail/events/update.rb +23 -7
- data/lib/paper_trail/frameworks/active_record.rb +9 -2
- data/lib/paper_trail/frameworks/rails/controller.rb +1 -9
- data/lib/paper_trail/frameworks/rails/railtie.rb +30 -0
- data/lib/paper_trail/frameworks/rails.rb +1 -2
- data/lib/paper_trail/has_paper_trail.rb +1 -1
- data/lib/paper_trail/model_config.rb +46 -46
- data/lib/paper_trail/queries/versions/where_attribute_changes.rb +50 -0
- data/lib/paper_trail/queries/versions/where_object.rb +1 -1
- data/lib/paper_trail/queries/versions/where_object_changes.rb +9 -14
- data/lib/paper_trail/queries/versions/where_object_changes_from.rb +57 -0
- data/lib/paper_trail/queries/versions/where_object_changes_to.rb +57 -0
- data/lib/paper_trail/record_trail.rb +80 -64
- data/lib/paper_trail/reifier.rb +41 -26
- data/lib/paper_trail/request.rb +22 -25
- data/lib/paper_trail/serializers/json.rb +0 -10
- data/lib/paper_trail/serializers/yaml.rb +38 -13
- data/lib/paper_trail/type_serializers/postgres_array_serializer.rb +1 -14
- data/lib/paper_trail/version_concern.rb +86 -41
- data/lib/paper_trail/version_number.rb +3 -3
- data/lib/paper_trail.rb +22 -40
- metadata +106 -45
- data/lib/paper_trail/frameworks/rails/engine.rb +0 -45
@@ -7,8 +7,6 @@ require "paper_trail/events/update"
|
|
7
7
|
module PaperTrail
|
8
8
|
# Represents the "paper trail" for a single record.
|
9
9
|
class RecordTrail
|
10
|
-
RAILS_GTE_5_1 = ::ActiveRecord.gem_version >= ::Gem::Version.new("5.1.0.beta1")
|
11
|
-
|
12
10
|
def initialize(record)
|
13
11
|
@record = record
|
14
12
|
end
|
@@ -27,14 +25,6 @@ module PaperTrail
|
|
27
25
|
@record.send("#{@record.class.version_association_name}=", nil)
|
28
26
|
end
|
29
27
|
|
30
|
-
# Is PT enabled for this particular record?
|
31
|
-
# @api private
|
32
|
-
def enabled?
|
33
|
-
PaperTrail.enabled? &&
|
34
|
-
PaperTrail.request.enabled? &&
|
35
|
-
PaperTrail.request.enabled_for_model?(@record.class)
|
36
|
-
end
|
37
|
-
|
38
28
|
# Returns true if this instance is the current, live one;
|
39
29
|
# returns false if this instance came from a previous version.
|
40
30
|
def live?
|
@@ -77,13 +67,6 @@ module PaperTrail
|
|
77
67
|
end
|
78
68
|
end
|
79
69
|
|
80
|
-
# PT-AT extends this method to add its transaction id.
|
81
|
-
#
|
82
|
-
# @api private
|
83
|
-
def data_for_create
|
84
|
-
{}
|
85
|
-
end
|
86
|
-
|
87
70
|
# `recording_order` is "after" or "before". See ModelConfig#on_destroy.
|
88
71
|
#
|
89
72
|
# @api private
|
@@ -107,14 +90,12 @@ module PaperTrail
|
|
107
90
|
end
|
108
91
|
end
|
109
92
|
|
110
|
-
# PT-AT extends this method to add its transaction id.
|
111
|
-
#
|
112
|
-
# @api private
|
113
|
-
def data_for_destroy
|
114
|
-
{}
|
115
|
-
end
|
116
|
-
|
117
93
|
# @api private
|
94
|
+
# @param force [boolean] Insert a `Version` even if `@record` has not
|
95
|
+
# `changed_notably?`.
|
96
|
+
# @param in_after_callback [boolean] True when called from an `after_update`
|
97
|
+
# or `after_touch` callback.
|
98
|
+
# @param is_touch [boolean] True when called from an `after_touch` callback.
|
118
99
|
# @return - The created version object, so that plugins can use it, e.g.
|
119
100
|
# paper_trail-association_tracking
|
120
101
|
def record_update(force:, in_after_callback:, is_touch:)
|
@@ -138,40 +119,6 @@ module PaperTrail
|
|
138
119
|
end
|
139
120
|
end
|
140
121
|
|
141
|
-
# PT-AT extends this method to add its transaction id.
|
142
|
-
#
|
143
|
-
# @api private
|
144
|
-
def data_for_update
|
145
|
-
{}
|
146
|
-
end
|
147
|
-
|
148
|
-
# @api private
|
149
|
-
# @return - The created version object, so that plugins can use it, e.g.
|
150
|
-
# paper_trail-association_tracking
|
151
|
-
def record_update_columns(changes)
|
152
|
-
return unless enabled?
|
153
|
-
event = Events::Update.new(@record, false, false, changes)
|
154
|
-
|
155
|
-
# Merge data from `Event` with data from PT-AT. We no longer use
|
156
|
-
# `data_for_update_columns` but PT-AT still does.
|
157
|
-
data = event.data.merge(data_for_update_columns)
|
158
|
-
|
159
|
-
versions_assoc = @record.send(@record.class.versions_association_name)
|
160
|
-
version = versions_assoc.create(data)
|
161
|
-
if version.errors.any?
|
162
|
-
log_version_errors(version, :update)
|
163
|
-
else
|
164
|
-
version
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
# PT-AT extends this method to add its transaction id.
|
169
|
-
#
|
170
|
-
# @api private
|
171
|
-
def data_for_update_columns
|
172
|
-
{}
|
173
|
-
end
|
174
|
-
|
175
122
|
# Invoked via callback when a user attempts to persist a reified
|
176
123
|
# `Version`.
|
177
124
|
def reset_timestamp_attrs_for_update_if_needed
|
@@ -196,15 +143,17 @@ module PaperTrail
|
|
196
143
|
# Save, and create a version record regardless of options such as `:on`,
|
197
144
|
# `:if`, or `:unless`.
|
198
145
|
#
|
199
|
-
#
|
146
|
+
# `in_after_callback`: Indicates if this method is being called within an
|
147
|
+
# `after` callback. Defaults to `false`.
|
148
|
+
# `options`: Optional arguments passed to `save`.
|
200
149
|
#
|
201
150
|
# This is an "update" event. That is, we record the same data we would in
|
202
151
|
# the case of a normal AR `update`.
|
203
|
-
def save_with_version(
|
152
|
+
def save_with_version(in_after_callback: false, **options)
|
204
153
|
::PaperTrail.request(enabled: false) do
|
205
|
-
@record.save(
|
154
|
+
@record.save(**options)
|
206
155
|
end
|
207
|
-
record_update(force: true, in_after_callback:
|
156
|
+
record_update(force: true, in_after_callback: in_after_callback, is_touch: false)
|
208
157
|
end
|
209
158
|
|
210
159
|
# Like the `update_column` method from `ActiveRecord::Persistence`, but also
|
@@ -269,11 +218,22 @@ module PaperTrail
|
|
269
218
|
def build_version_on_update(force:, in_after_callback:, is_touch:)
|
270
219
|
event = Events::Update.new(@record, in_after_callback, is_touch, nil)
|
271
220
|
return unless force || event.changed_notably?
|
221
|
+
data = event.data
|
222
|
+
|
223
|
+
# Copy the (recently set) `updated_at` from the record to the `created_at`
|
224
|
+
# of the `Version`. Without this feature, these two timestamps would
|
225
|
+
# differ by a few milliseconds. To some people, it seems a little
|
226
|
+
# unnatural to tamper with creation timestamps in this way. But, this
|
227
|
+
# feature has existed for a long time, almost a decade now, and some users
|
228
|
+
# may rely on it now.
|
229
|
+
if @record.respond_to?(:updated_at)
|
230
|
+
data[:created_at] = @record.updated_at
|
231
|
+
end
|
272
232
|
|
273
233
|
# Merge data from `Event` with data from PT-AT. We no longer use
|
274
234
|
# `data_for_update` but PT-AT still does. To save memory, we use `merge!`
|
275
235
|
# instead of `merge`.
|
276
|
-
data
|
236
|
+
data.merge!(data_for_update)
|
277
237
|
|
278
238
|
# Using `version_class.new` reduces memory usage compared to
|
279
239
|
# `versions_assoc.build`. It's a trade-off though. We have to clear
|
@@ -282,13 +242,69 @@ module PaperTrail
|
|
282
242
|
@record.class.paper_trail.version_class.new(data)
|
283
243
|
end
|
284
244
|
|
245
|
+
# PT-AT extends this method to add its transaction id.
|
246
|
+
#
|
247
|
+
# @api public
|
248
|
+
def data_for_create
|
249
|
+
{}
|
250
|
+
end
|
251
|
+
|
252
|
+
# PT-AT extends this method to add its transaction id.
|
253
|
+
#
|
254
|
+
# @api public
|
255
|
+
def data_for_destroy
|
256
|
+
{}
|
257
|
+
end
|
258
|
+
|
259
|
+
# PT-AT extends this method to add its transaction id.
|
260
|
+
#
|
261
|
+
# @api public
|
262
|
+
def data_for_update
|
263
|
+
{}
|
264
|
+
end
|
265
|
+
|
266
|
+
# PT-AT extends this method to add its transaction id.
|
267
|
+
#
|
268
|
+
# @api public
|
269
|
+
def data_for_update_columns
|
270
|
+
{}
|
271
|
+
end
|
272
|
+
|
273
|
+
# Is PT enabled for this particular record?
|
274
|
+
# @api private
|
275
|
+
def enabled?
|
276
|
+
PaperTrail.enabled? &&
|
277
|
+
PaperTrail.request.enabled? &&
|
278
|
+
PaperTrail.request.enabled_for_model?(@record.class)
|
279
|
+
end
|
280
|
+
|
285
281
|
def log_version_errors(version, action)
|
286
282
|
version.logger&.warn(
|
287
283
|
"Unable to create version for #{action} of #{@record.class.name}" \
|
288
|
-
|
284
|
+
"##{@record.id}: " + version.errors.full_messages.join(", ")
|
289
285
|
)
|
290
286
|
end
|
291
287
|
|
288
|
+
# @api private
|
289
|
+
# @return - The created version object, so that plugins can use it, e.g.
|
290
|
+
# paper_trail-association_tracking
|
291
|
+
def record_update_columns(changes)
|
292
|
+
return unless enabled?
|
293
|
+
data = Events::Update.new(@record, false, false, changes).data
|
294
|
+
|
295
|
+
# Merge data from `Event` with data from PT-AT. We no longer use
|
296
|
+
# `data_for_update_columns` but PT-AT still does.
|
297
|
+
data.merge!(data_for_update_columns)
|
298
|
+
|
299
|
+
versions_assoc = @record.send(@record.class.versions_association_name)
|
300
|
+
version = versions_assoc.create(data)
|
301
|
+
if version.errors.any?
|
302
|
+
log_version_errors(version, :update)
|
303
|
+
else
|
304
|
+
version
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
292
308
|
def version
|
293
309
|
@record.public_send(@record.class.version_association_name)
|
294
310
|
end
|
data/lib/paper_trail/reifier.rb
CHANGED
@@ -52,26 +52,29 @@ module PaperTrail
|
|
52
52
|
# not the actual subclass. If `type` is present but empty, the class is
|
53
53
|
# the base class.
|
54
54
|
def init_model(attrs, options, version)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
model = item_found
|
69
|
-
init_unversioned_attrs(attrs, model)
|
70
|
-
end
|
55
|
+
klass = version_reification_class(version, attrs)
|
56
|
+
|
57
|
+
# The `dup` option and destroyed version always returns a new object,
|
58
|
+
# otherwise we should attempt to load item or to look for the item
|
59
|
+
# outside of default scope(s).
|
60
|
+
model = if options[:dup] == true || version.event == "destroy"
|
61
|
+
klass.new
|
62
|
+
else
|
63
|
+
version.item || init_model_by_finding_item_id(klass, version) || klass.new
|
64
|
+
end
|
65
|
+
|
66
|
+
if options[:unversioned_attributes] == :nil && !model.new_record?
|
67
|
+
init_unversioned_attrs(attrs, model)
|
71
68
|
end
|
69
|
+
|
72
70
|
model
|
73
71
|
end
|
74
72
|
|
73
|
+
# @api private
|
74
|
+
def init_model_by_finding_item_id(klass, version)
|
75
|
+
klass.unscoped.where(klass.primary_key => version.item_id).first
|
76
|
+
end
|
77
|
+
|
75
78
|
# Look for attributes that exist in `model` and not in this version.
|
76
79
|
# These attributes should be set to nil. Modifies `attrs`.
|
77
80
|
# @api private
|
@@ -88,9 +91,7 @@ module PaperTrail
|
|
88
91
|
#
|
89
92
|
# @api private
|
90
93
|
def reify_attribute(k, v, model, version)
|
91
|
-
|
92
|
-
is_enum_without_type_caster = ::ActiveRecord::VERSION::MAJOR < 5 && enums.key?(k)
|
93
|
-
if model.has_attribute?(k) && !is_enum_without_type_caster
|
94
|
+
if model.has_attribute?(k)
|
94
95
|
model[k.to_sym] = v
|
95
96
|
elsif model.respond_to?("#{k}=")
|
96
97
|
model.send("#{k}=", v)
|
@@ -111,21 +112,35 @@ module PaperTrail
|
|
111
112
|
end
|
112
113
|
|
113
114
|
# Given a `version`, return the class to reify. This method supports
|
114
|
-
# Single Table Inheritance (STI) with custom inheritance columns
|
115
|
+
# Single Table Inheritance (STI) with custom inheritance columns and
|
116
|
+
# custom inheritance column values.
|
115
117
|
#
|
116
118
|
# For example, imagine a `version` whose `item_type` is "Animal". The
|
117
119
|
# `animals` table is an STI table (it has cats and dogs) and it has a
|
118
120
|
# custom inheritance column, `species`. If `attrs["species"]` is "Dog",
|
119
121
|
# this method returns the constant `Dog`. If `attrs["species"]` is blank,
|
120
|
-
# this method returns the constant `Animal`.
|
121
|
-
#
|
122
|
+
# this method returns the constant `Animal`.
|
123
|
+
#
|
124
|
+
# The values contained in the inheritance columns may be non-camelized
|
125
|
+
# strings (e.g. 'dog' instead of 'Dog'). To reify classes in this case
|
126
|
+
# we need to call the parents class `sti_class_for` method to retrieve
|
127
|
+
# the correct record class.
|
122
128
|
#
|
123
|
-
#
|
129
|
+
# You can see these particular examples in action in
|
130
|
+
# `spec/models/animal_spec.rb` and `spec/models/plant_spec.rb`
|
124
131
|
def version_reification_class(version, attrs)
|
125
|
-
|
132
|
+
clazz = version.item_type.constantize
|
133
|
+
inheritance_column_name = clazz.inheritance_column
|
126
134
|
inher_col_value = attrs[inheritance_column_name]
|
127
|
-
|
128
|
-
|
135
|
+
return clazz if inher_col_value.blank?
|
136
|
+
|
137
|
+
# Rails 6.1 adds a public method for clients to use to customize STI classes. If that
|
138
|
+
# method is not available, fall back to using the private one
|
139
|
+
if clazz.public_methods.include?(:sti_class_for)
|
140
|
+
return clazz.sti_class_for(inher_col_value)
|
141
|
+
end
|
142
|
+
|
143
|
+
clazz.send(:find_sti_class, inher_col_value)
|
129
144
|
end
|
130
145
|
end
|
131
146
|
end
|
data/lib/paper_trail/request.rb
CHANGED
@@ -12,9 +12,6 @@ module PaperTrail
|
|
12
12
|
#
|
13
13
|
# @api private
|
14
14
|
module Request
|
15
|
-
class InvalidOption < RuntimeError
|
16
|
-
end
|
17
|
-
|
18
15
|
class << self
|
19
16
|
# Sets any data from the controller that you want PaperTrail to store.
|
20
17
|
# See also `PaperTrail::Rails::Controller#info_for_paper_trail`.
|
@@ -78,28 +75,6 @@ module PaperTrail
|
|
78
75
|
!!store.fetch(:"enabled_for_#{model}", true)
|
79
76
|
end
|
80
77
|
|
81
|
-
# @api private
|
82
|
-
def merge(options)
|
83
|
-
options.to_h.each do |k, v|
|
84
|
-
store[k] = v
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# @api private
|
89
|
-
def set(options)
|
90
|
-
store.clear
|
91
|
-
merge(options)
|
92
|
-
end
|
93
|
-
|
94
|
-
# Returns a deep copy of the internal hash from our RequestStore. Keys are
|
95
|
-
# all symbols. Values are mostly primitives, but whodunnit can be a Proc.
|
96
|
-
# We cannot use Marshal.dump here because it doesn't support Proc. It is
|
97
|
-
# unclear exactly how `deep_dup` handles a Proc, but it doesn't complain.
|
98
|
-
# @api private
|
99
|
-
def to_h
|
100
|
-
store.deep_dup
|
101
|
-
end
|
102
|
-
|
103
78
|
# Temporarily set `options` and execute a block.
|
104
79
|
# @api private
|
105
80
|
def with(options)
|
@@ -136,6 +111,19 @@ module PaperTrail
|
|
136
111
|
|
137
112
|
private
|
138
113
|
|
114
|
+
# @api private
|
115
|
+
def merge(options)
|
116
|
+
options.to_h.each do |k, v|
|
117
|
+
store[k] = v
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# @api private
|
122
|
+
def set(options)
|
123
|
+
store.clear
|
124
|
+
merge(options)
|
125
|
+
end
|
126
|
+
|
139
127
|
# Returns a Hash, initializing with default values if necessary.
|
140
128
|
# @api private
|
141
129
|
def store
|
@@ -144,6 +132,15 @@ module PaperTrail
|
|
144
132
|
}
|
145
133
|
end
|
146
134
|
|
135
|
+
# Returns a deep copy of the internal hash from our RequestStore. Keys are
|
136
|
+
# all symbols. Values are mostly primitives, but whodunnit can be a Proc.
|
137
|
+
# We cannot use Marshal.dump here because it doesn't support Proc. It is
|
138
|
+
# unclear exactly how `deep_dup` handles a Proc, but it doesn't complain.
|
139
|
+
# @api private
|
140
|
+
def to_h
|
141
|
+
store.deep_dup
|
142
|
+
end
|
143
|
+
|
147
144
|
# Provide a helpful error message if someone has a typo in one of their
|
148
145
|
# option keys. We don't validate option values here. That's traditionally
|
149
146
|
# been handled with casting (`to_s`, `!!`) in the accessor method.
|
@@ -31,16 +31,6 @@ module PaperTrail
|
|
31
31
|
arel_field.matches("%\"#{field}\":#{json_value}%")
|
32
32
|
end
|
33
33
|
end
|
34
|
-
|
35
|
-
def where_object_changes_condition(*)
|
36
|
-
raise <<-STR.squish.freeze
|
37
|
-
where_object_changes no longer supports reading JSON from a text
|
38
|
-
column. The old implementation was inaccurate, returning more records
|
39
|
-
than you wanted. This feature was deprecated in 7.1.0 and removed in
|
40
|
-
8.0.0. The json and jsonb datatypes are still supported. See the
|
41
|
-
discussion at https://github.com/paper-trail-gem/paper_trail/issues/803
|
42
|
-
STR
|
43
|
-
end
|
44
34
|
end
|
45
35
|
end
|
46
36
|
end
|
@@ -9,13 +9,23 @@ module PaperTrail
|
|
9
9
|
extend self # makes all instance methods become module methods as well
|
10
10
|
|
11
11
|
def load(string)
|
12
|
-
|
12
|
+
if use_safe_load?
|
13
|
+
::YAML.safe_load(
|
14
|
+
string,
|
15
|
+
permitted_classes: yaml_column_permitted_classes,
|
16
|
+
aliases: true
|
17
|
+
)
|
18
|
+
elsif ::YAML.respond_to?(:unsafe_load)
|
19
|
+
::YAML.unsafe_load(string)
|
20
|
+
else
|
21
|
+
::YAML.load(string)
|
22
|
+
end
|
13
23
|
end
|
14
24
|
|
15
25
|
# @param object (Hash | HashWithIndifferentAccess) - Coming from
|
16
26
|
# `recordable_object` `object` will be a plain `Hash`. However, due to
|
17
|
-
# recent [memory optimizations](https://
|
18
|
-
# `recordable_object_changes`, it will be a `HashWithIndifferentAccess`.
|
27
|
+
# recent [memory optimizations](https://github.com/paper-trail-gem/paper_trail/pull/1189),
|
28
|
+
# when coming from `recordable_object_changes`, it will be a `HashWithIndifferentAccess`.
|
19
29
|
def dump(object)
|
20
30
|
object = object.to_hash if object.is_a?(HashWithIndifferentAccess)
|
21
31
|
::YAML.dump object
|
@@ -27,16 +37,31 @@ module PaperTrail
|
|
27
37
|
arel_field.matches("%\n#{field}: #{value}\n%")
|
28
38
|
end
|
29
39
|
|
30
|
-
|
31
|
-
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
+
private
|
41
|
+
|
42
|
+
def use_safe_load?
|
43
|
+
if ::ActiveRecord.gem_version >= Gem::Version.new("7.0.3.1")
|
44
|
+
# `use_yaml_unsafe_load` may be removed in the future, at which point
|
45
|
+
# safe loading will be the default.
|
46
|
+
!defined?(ActiveRecord.use_yaml_unsafe_load) || !ActiveRecord.use_yaml_unsafe_load
|
47
|
+
elsif defined?(ActiveRecord::Base.use_yaml_unsafe_load)
|
48
|
+
# Rails 5.2.8.1, 6.0.5.1, 6.1.6.1
|
49
|
+
!ActiveRecord::Base.use_yaml_unsafe_load
|
50
|
+
else
|
51
|
+
false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def yaml_column_permitted_classes
|
56
|
+
if defined?(ActiveRecord.yaml_column_permitted_classes)
|
57
|
+
# Rails >= 7.0.3.1
|
58
|
+
ActiveRecord.yaml_column_permitted_classes
|
59
|
+
elsif defined?(ActiveRecord::Base.yaml_column_permitted_classes)
|
60
|
+
# Rails 5.2.8.1, 6.0.5.1, 6.1.6.1
|
61
|
+
ActiveRecord::Base.yaml_column_permitted_classes
|
62
|
+
else
|
63
|
+
[]
|
64
|
+
end
|
40
65
|
end
|
41
66
|
end
|
42
67
|
end
|
@@ -11,15 +11,12 @@ module PaperTrail
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def serialize(array)
|
14
|
-
return serialize_with_ar(array) if active_record_pre_502?
|
15
14
|
array
|
16
15
|
end
|
17
16
|
|
18
17
|
def deserialize(array)
|
19
|
-
return deserialize_with_ar(array) if active_record_pre_502?
|
20
|
-
|
21
18
|
case array
|
22
|
-
# Needed for legacy
|
19
|
+
# Needed for legacy data. If serialized array is a string
|
23
20
|
# then it was serialized with Rails < 5.0.2.
|
24
21
|
when ::String then deserialize_with_ar(array)
|
25
22
|
else array
|
@@ -28,16 +25,6 @@ module PaperTrail
|
|
28
25
|
|
29
26
|
private
|
30
27
|
|
31
|
-
def active_record_pre_502?
|
32
|
-
::ActiveRecord.gem_version < Gem::Version.new("5.0.2")
|
33
|
-
end
|
34
|
-
|
35
|
-
def serialize_with_ar(array)
|
36
|
-
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array.
|
37
|
-
new(@subtype, @delimiter).
|
38
|
-
serialize(array)
|
39
|
-
end
|
40
|
-
|
41
28
|
def deserialize_with_ar(array)
|
42
29
|
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array.
|
43
30
|
new(@subtype, @delimiter).
|