snail_trail 1.0.0 → 1.1.0.rc.pre.1
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/lib/snail_trail/frameworks/rails/controller.rb +10 -0
- data/lib/snail_trail/model_config.rb +12 -2
- data/lib/snail_trail/record_trail.rb +192 -154
- data/lib/snail_trail/reifier.rb +1 -1
- data/lib/snail_trail/request.rb +76 -42
- data/lib/snail_trail/version_concern.rb +3 -3
- data/lib/snail_trail/version_number.rb +2 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9615c601651c566fd33af08844a5aa454394269af10c4b955c95864ccf364963
|
4
|
+
data.tar.gz: 4656e2e38cfb1ed9155ec37b676e46e4cd8533c5db54118c69e55177d95223d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32cb46bf800abafcf3b16efd74ace9e398cf7cb366310ed48bdc2cd14ec375036543e3699d9f97359cfa4a2c42882c67d555fab442bfd93ae3902f54ff020547
|
7
|
+
data.tar.gz: 3377f9f5af34d50de4dcaca784fb1b6d6cb8190801496418b02a7aefc7494801f92bac6172b5c0d83c13dd3b976f0dc285868c1fa24556f71d89dedb9cdb4ab6
|
@@ -89,6 +89,16 @@ module SnailTrail
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
+
# Tells SnailTrail to run in performance mode.
|
93
|
+
#
|
94
|
+
# @api public
|
95
|
+
#
|
96
|
+
def set_snail_trail_performance_mode
|
97
|
+
if ::SnailTrail.request.enabled?
|
98
|
+
::SnailTrail.request.performance_mode!
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
92
102
|
# Tells SnailTrail any information from the controller you want to store
|
93
103
|
# alongside any changes that occur.
|
94
104
|
#
|
@@ -126,8 +126,18 @@ module SnailTrail
|
|
126
126
|
|
127
127
|
# Reset the transaction id when the transaction is closed.
|
128
128
|
def setup_transaction_callbacks
|
129
|
-
@model_class.after_commit
|
130
|
-
|
129
|
+
@model_class.after_commit do |r|
|
130
|
+
::SnailTrail.request.clear_transaction_id
|
131
|
+
|
132
|
+
r.snail_trail.record_performance_data
|
133
|
+
|
134
|
+
::SnailTrail.request.clear_performance_mode
|
135
|
+
end
|
136
|
+
|
137
|
+
@model_class.after_rollback do
|
138
|
+
::SnailTrail.request.clear_transaction_id
|
139
|
+
::SnailTrail.request.clear_performance_mode
|
140
|
+
end
|
131
141
|
end
|
132
142
|
|
133
143
|
# @api private
|
@@ -58,17 +58,23 @@ module SnailTrail
|
|
58
58
|
def record_create
|
59
59
|
return unless enabled?
|
60
60
|
|
61
|
-
build_version_on_create(in_after_callback: true)
|
62
|
-
version.save!
|
61
|
+
version = build_version_on_create(in_after_callback: true)
|
63
62
|
|
64
|
-
|
63
|
+
if ::SnailTrail.request.performance_mode?
|
64
|
+
::SnailTrail.request.performance_mode_data << version.attributes
|
65
|
+
else
|
66
|
+
begin
|
67
|
+
version.save!
|
65
68
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
update_transaction_id(version)
|
70
|
+
|
71
|
+
# Because the version object was created using version_class.new instead
|
72
|
+
# of versions_assoc.build?, the association cache is unaware. So, we
|
73
|
+
# invalidate the `versions` association cache with `reset`.
|
74
|
+
versions.reset
|
75
|
+
rescue StandardError => e
|
76
|
+
handle_version_errors e, version, :create
|
77
|
+
end
|
72
78
|
end
|
73
79
|
end
|
74
80
|
|
@@ -82,22 +88,25 @@ module SnailTrail
|
|
82
88
|
in_after_callback = recording_order == "after"
|
83
89
|
event = Events::Destroy.new(@record, in_after_callback)
|
84
90
|
|
85
|
-
# Merge data from `Event` with data from ST-AT. We no longer use
|
86
|
-
# `data_for_destroy` but ST-AT still does.
|
87
91
|
data = event.data.merge(data_for_destroy)
|
88
92
|
|
89
93
|
version = @record.class.snail_trail.version_class.new(data)
|
90
|
-
begin
|
91
|
-
version.save!
|
92
|
-
assign_and_reset_version_association(version)
|
93
94
|
|
94
|
-
|
95
|
-
|
96
|
-
|
95
|
+
if ::SnailTrail.request.performance_mode?
|
96
|
+
::SnailTrail.request.performance_mode_data << version.attributes
|
97
|
+
else
|
98
|
+
begin
|
99
|
+
version.save!
|
100
|
+
assign_and_reset_version_association(version)
|
101
|
+
|
102
|
+
if version && version.respond_to?(:errors) && version.errors.empty?
|
103
|
+
update_transaction_id(version)
|
104
|
+
end
|
97
105
|
|
98
|
-
|
99
|
-
|
100
|
-
|
106
|
+
version
|
107
|
+
rescue StandardError => e
|
108
|
+
handle_version_errors e, version, :destroy
|
109
|
+
end
|
101
110
|
end
|
102
111
|
end
|
103
112
|
|
@@ -119,20 +128,50 @@ module SnailTrail
|
|
119
128
|
)
|
120
129
|
return unless version
|
121
130
|
|
122
|
-
|
123
|
-
version.
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
131
|
+
if ::SnailTrail.request.performance_mode?
|
132
|
+
::SnailTrail.request.performance_mode_data << version.attributes
|
133
|
+
else
|
134
|
+
begin
|
135
|
+
version.save!
|
136
|
+
# Because the version object was created using version_class.new instead
|
137
|
+
# of versions_assoc.build?, the association cache is unaware. So, we
|
138
|
+
# invalidate the `versions` association cache with `reset`.
|
139
|
+
versions.reset
|
140
|
+
|
141
|
+
if version && version.respond_to?(:errors) && version.errors.empty?
|
142
|
+
update_transaction_id(version)
|
143
|
+
end
|
144
|
+
|
145
|
+
version
|
146
|
+
rescue StandardError => e
|
147
|
+
handle_version_errors e, version, :update
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def record_performance_data
|
153
|
+
return unless ::SnailTrail.request.performance_mode?
|
154
|
+
|
155
|
+
all_data = ::SnailTrail.request.performance_mode_data
|
156
|
+
first_data = all_data.shift
|
157
|
+
version = @record.class.snail_trail.version_class.create(first_data)
|
158
|
+
update_transaction_id(version)
|
159
|
+
all_data.each_slice(1_000) do |datas|
|
160
|
+
timestamp = Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")
|
161
|
+
datas.each do |d|
|
162
|
+
add_transaction_id_to(d)
|
163
|
+
d['created_at'] = timestamp
|
164
|
+
d['event'] = "batch_#{d['event']}"
|
165
|
+
end
|
128
166
|
|
129
|
-
|
130
|
-
|
167
|
+
sql = ["INSERT INTO #{version.class.table_name} (#{datas.first.keys.join(", ")}) VALUES"]
|
168
|
+
datas.map do |data|
|
169
|
+
values = data.map { |k, v| @record.class.connection.quote(v.is_a?(Hash) ? JSON.generate(v) : v) }
|
170
|
+
sql << "(#{values.join(", ")}),"
|
131
171
|
end
|
172
|
+
sql.last.chop!
|
132
173
|
|
133
|
-
|
134
|
-
rescue StandardError => e
|
135
|
-
handle_version_errors e, version, :update
|
174
|
+
@record.class.snail_trail.version_class.connection.execute(sql.join("\n"))
|
136
175
|
end
|
137
176
|
end
|
138
177
|
|
@@ -218,7 +257,6 @@ module SnailTrail
|
|
218
257
|
data[:transaction_id] = ::SnailTrail.request.transaction_id
|
219
258
|
end
|
220
259
|
|
221
|
-
|
222
260
|
def update_transaction_id(version)
|
223
261
|
return unless @record.class.snail_trail.version_class.column_names.include?("transaction_id")
|
224
262
|
if ::SnailTrail.transaction? && ::SnailTrail.request.transaction_id.nil?
|
@@ -228,148 +266,148 @@ module SnailTrail
|
|
228
266
|
end
|
229
267
|
end
|
230
268
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
# @api private
|
238
|
-
def build_version_on_create(in_after_callback:)
|
239
|
-
event = Events::Create.new(@record, in_after_callback)
|
269
|
+
# @api private
|
270
|
+
def assign_and_reset_version_association(version)
|
271
|
+
@record.send(:"#{@record.class.version_association_name}=", version)
|
272
|
+
@record.send(@record.class.versions_association_name).reset
|
273
|
+
end
|
240
274
|
|
241
|
-
#
|
242
|
-
|
243
|
-
|
275
|
+
# @api private
|
276
|
+
def build_version_on_create(in_after_callback:)
|
277
|
+
event = Events::Create.new(@record, in_after_callback)
|
244
278
|
|
245
|
-
|
246
|
-
|
247
|
-
|
279
|
+
# Merge data from `Event` with data from ST-AT. We no longer use
|
280
|
+
# `data_for_create` but ST-AT still does.
|
281
|
+
data = event.data.merge!(data_for_create)
|
248
282
|
|
249
|
-
|
250
|
-
|
251
|
-
event = Events::Update.new(@record, in_after_callback, is_touch, nil)
|
252
|
-
return unless force || event.changed_notably?
|
253
|
-
data = event.data
|
254
|
-
|
255
|
-
# Copy the (recently set) `updated_at` from the record to the `created_at`
|
256
|
-
# of the `Version`. Without this feature, these two timestamps would
|
257
|
-
# differ by a few milliseconds. To some people, it seems a little
|
258
|
-
# unnatural to tamper with creation timestamps in this way. But, this
|
259
|
-
# feature has existed for a long time, almost a decade now, and some users
|
260
|
-
# may rely on it now.
|
261
|
-
if @record.respond_to?(:updated_at) &&
|
262
|
-
@record.snail_trail_options[:synchronize_version_creation_timestamp] != false
|
263
|
-
data[:created_at] = @record.updated_at
|
283
|
+
# Pure `version_class.new` reduces memory usage compared to `versions_assoc.build`
|
284
|
+
@record.class.snail_trail.version_class.new(data)
|
264
285
|
end
|
265
286
|
|
266
|
-
#
|
267
|
-
|
268
|
-
|
269
|
-
|
287
|
+
# @api private
|
288
|
+
def build_version_on_update(force:, in_after_callback:, is_touch:)
|
289
|
+
event = Events::Update.new(@record, in_after_callback, is_touch, nil)
|
290
|
+
return unless force || event.changed_notably?
|
291
|
+
data = event.data
|
292
|
+
|
293
|
+
# Copy the (recently set) `updated_at` from the record to the `created_at`
|
294
|
+
# of the `Version`. Without this feature, these two timestamps would
|
295
|
+
# differ by a few milliseconds. To some people, it seems a little
|
296
|
+
# unnatural to tamper with creation timestamps in this way. But, this
|
297
|
+
# feature has existed for a long time, almost a decade now, and some users
|
298
|
+
# may rely on it now.
|
299
|
+
if @record.respond_to?(:updated_at) &&
|
300
|
+
@record.snail_trail_options[:synchronize_version_creation_timestamp] != false
|
301
|
+
data[:created_at] = @record.updated_at
|
302
|
+
end
|
270
303
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
@record.class.snail_trail.version_class.new(data)
|
276
|
-
end
|
304
|
+
# Merge data from `Event` with data from ST-AT. We no longer use
|
305
|
+
# `data_for_update` but ST-AT still does. To save memory, we use `merge!`
|
306
|
+
# instead of `merge`.
|
307
|
+
data.merge!(data_for_update)
|
277
308
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
309
|
+
# Using `version_class.new` reduces memory usage compared to
|
310
|
+
# `versions_assoc.build`. It's a trade-off though. We have to clear
|
311
|
+
# the association cache (see `versions.reset`) and that could cause an
|
312
|
+
# additional query in certain applications.
|
313
|
+
@record.class.snail_trail.version_class.new(data)
|
314
|
+
end
|
284
315
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
316
|
+
# @api public
|
317
|
+
def data_for_create
|
318
|
+
data = {}
|
319
|
+
add_transaction_id_to(data)
|
320
|
+
data
|
321
|
+
end
|
291
322
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
323
|
+
# @api public
|
324
|
+
def data_for_destroy
|
325
|
+
data = {}
|
326
|
+
add_transaction_id_to(data)
|
327
|
+
data
|
328
|
+
end
|
298
329
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
330
|
+
# @api public
|
331
|
+
def data_for_update
|
332
|
+
data = {}
|
333
|
+
add_transaction_id_to(data)
|
334
|
+
data
|
335
|
+
end
|
305
336
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
end
|
337
|
+
# @api public
|
338
|
+
def data_for_update_columns
|
339
|
+
data = {}
|
340
|
+
add_transaction_id_to(data)
|
341
|
+
data
|
342
|
+
end
|
313
343
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
344
|
+
# Is ST enabled for this particular record?
|
345
|
+
# @api private
|
346
|
+
def enabled?
|
347
|
+
SnailTrail.enabled? &&
|
348
|
+
SnailTrail.request.enabled? &&
|
349
|
+
SnailTrail.request.enabled_for_model?(@record.class)
|
350
|
+
end
|
320
351
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
352
|
+
def log_version_errors(version, action)
|
353
|
+
version.logger&.warn(
|
354
|
+
"Unable to create version for #{action} of #{@record.class.name}" \
|
355
|
+
"##{@record.id}: " + version.errors.full_messages.join(", ")
|
356
|
+
)
|
357
|
+
end
|
358
|
+
|
359
|
+
# Centralized handler for version errors
|
360
|
+
# @api private
|
361
|
+
def handle_version_errors(e, version, action)
|
362
|
+
case SnailTrail.config.version_error_behavior
|
363
|
+
when :legacy
|
364
|
+
# legacy behavior was to raise on create and log on update/delete
|
365
|
+
if action == :create
|
366
|
+
raise e
|
367
|
+
else
|
368
|
+
log_version_errors(version, action)
|
369
|
+
end
|
370
|
+
when :log
|
330
371
|
log_version_errors(version, action)
|
372
|
+
when :exception
|
373
|
+
raise e
|
374
|
+
when :silent
|
375
|
+
# noop
|
331
376
|
end
|
332
|
-
when :log
|
333
|
-
log_version_errors(version, action)
|
334
|
-
when :exception
|
335
|
-
raise e
|
336
|
-
when :silent
|
337
|
-
# noop
|
338
377
|
end
|
339
|
-
end
|
340
|
-
|
341
|
-
# @api private
|
342
|
-
# @return - The created version object, so that plugins can use it, e.g.
|
343
|
-
# snail_trail-association_tracking
|
344
|
-
def record_update_columns(changes)
|
345
|
-
return unless enabled?
|
346
|
-
data = Events::Update.new(@record, false, false, changes).data
|
347
|
-
|
348
|
-
# Merge data from `Event` with data from ST-AT. We no longer use
|
349
|
-
# `data_for_update_columns` but ST-AT still does.
|
350
|
-
data.merge!(data_for_update_columns)
|
351
|
-
|
352
|
-
versions_assoc = @record.send(@record.class.versions_association_name)
|
353
|
-
version = versions_assoc.new(data)
|
354
|
-
begin
|
355
|
-
version.save!
|
356
378
|
|
357
|
-
|
358
|
-
|
379
|
+
# @api private
|
380
|
+
# @return - The created version object, so that plugins can use it, e.g.
|
381
|
+
# snail_trail-association_tracking
|
382
|
+
def record_update_columns(changes)
|
383
|
+
return unless enabled?
|
384
|
+
data = Events::Update.new(@record, false, false, changes).data
|
385
|
+
|
386
|
+
# Merge data from `Event` with data from ST-AT. We no longer use
|
387
|
+
# `data_for_update_columns` but ST-AT still does.
|
388
|
+
data.merge!(data_for_update_columns)
|
389
|
+
|
390
|
+
versions_assoc = @record.send(@record.class.versions_association_name)
|
391
|
+
version = versions_assoc.new(data)
|
392
|
+
begin
|
393
|
+
version.save!
|
394
|
+
|
395
|
+
if version && version.respond_to?(:errors) && version.errors.empty?
|
396
|
+
update_transaction_id(version)
|
397
|
+
end
|
398
|
+
|
399
|
+
version
|
400
|
+
rescue StandardError => e
|
401
|
+
handle_version_errors e, version, :update
|
359
402
|
end
|
360
|
-
|
361
|
-
version
|
362
|
-
rescue StandardError => e
|
363
|
-
handle_version_errors e, version, :update
|
364
403
|
end
|
365
|
-
end
|
366
404
|
|
367
|
-
|
368
|
-
|
369
|
-
|
405
|
+
def version
|
406
|
+
@record.public_send(@record.class.version_association_name)
|
407
|
+
end
|
370
408
|
|
371
|
-
|
372
|
-
|
373
|
-
|
409
|
+
def versions
|
410
|
+
@record.public_send(@record.class.versions_association_name)
|
411
|
+
end
|
374
412
|
end
|
375
413
|
end
|
data/lib/snail_trail/reifier.rb
CHANGED
@@ -57,7 +57,7 @@ module SnailTrail
|
|
57
57
|
# The `dup` option and destroyed version always returns a new object,
|
58
58
|
# otherwise we should attempt to load item or to look for the item
|
59
59
|
# outside of default scope(s).
|
60
|
-
model = if options[:dup] == true || version.event == "destroy"
|
60
|
+
model = if options[:dup] == true || version.event == "destroy" || version.event == "batch_destroy"
|
61
61
|
klass.new
|
62
62
|
else
|
63
63
|
version.item || init_model_by_finding_item_id(klass, version) || klass.new
|
data/lib/snail_trail/request.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require "request_store"
|
4
4
|
|
5
5
|
module SnailTrail
|
6
|
-
# Manages variables that affect the current HTTP request, such as `whodunnit`.
|
6
|
+
# Manages variables that affect the current HTTP request, such as `whodunnit` and `performance_mode`.
|
7
7
|
#
|
8
8
|
# Please do not use `SnailTrail::Request` directly, use `SnailTrail.request`.
|
9
9
|
# Currently, `Request` is a `Module`, but in the future it is quite possible
|
@@ -96,7 +96,7 @@ module SnailTrail
|
|
96
96
|
return unless block_given?
|
97
97
|
validate_public_options(options)
|
98
98
|
before = to_h
|
99
|
-
merge(options)
|
99
|
+
merge({ performance_mode: false, performance_mode_data: nil }.merge(options))
|
100
100
|
yield
|
101
101
|
ensure
|
102
102
|
set(before)
|
@@ -124,57 +124,91 @@ module SnailTrail
|
|
124
124
|
who.respond_to?(:call) ? who.call : who
|
125
125
|
end
|
126
126
|
|
127
|
-
|
127
|
+
# Enables performance mode for this request
|
128
|
+
def performance_mode!
|
129
|
+
self.performance_mode = true
|
130
|
+
end
|
128
131
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
store[k] = v
|
133
|
-
end
|
132
|
+
def clear_performance_mode
|
133
|
+
self.performance_mode = false
|
134
|
+
self.performance_mode_data = nil
|
134
135
|
end
|
135
136
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
137
|
+
def performance_mode= val
|
138
|
+
store[:performance_mode] = !!val
|
139
|
+
|
140
|
+
if performance_mode?
|
141
|
+
self.performance_mode_data = []
|
142
|
+
end
|
143
|
+
|
144
|
+
performance_mode?
|
140
145
|
end
|
141
146
|
|
142
|
-
# Returns
|
143
|
-
#
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
147
|
+
# Returns whether or not performance mode is enabled for this request
|
148
|
+
# Default: disabled
|
149
|
+
#
|
150
|
+
# @api public
|
151
|
+
#
|
152
|
+
def performance_mode?
|
153
|
+
!!store[:performance_mode]
|
148
154
|
end
|
149
155
|
|
150
|
-
|
151
|
-
|
152
|
-
# We cannot use Marshal.dump here because it doesn't support Proc. It is
|
153
|
-
# unclear exactly how `deep_dup` handles a Proc, but it doesn't complain.
|
154
|
-
# @api private
|
155
|
-
def to_h
|
156
|
-
store.deep_dup
|
156
|
+
def performance_mode_data
|
157
|
+
store[:performance_mode_data]
|
157
158
|
end
|
158
159
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
160
|
+
private
|
161
|
+
|
162
|
+
def performance_mode_data= val
|
163
|
+
store[:performance_mode_data] = val
|
164
|
+
end
|
165
|
+
|
166
|
+
# @api private
|
167
|
+
def merge(options)
|
168
|
+
options.to_h.each do |k, v|
|
169
|
+
store[k] = v
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# @api private
|
174
|
+
def set(options)
|
175
|
+
store.clear
|
176
|
+
merge(options)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Returns a Hash, initializing with default values if necessary.
|
180
|
+
# @api private
|
181
|
+
def store
|
182
|
+
RequestStore.store[:snail_trail] ||= {
|
183
|
+
enabled: true
|
184
|
+
}
|
185
|
+
end
|
186
|
+
|
187
|
+
# Returns a deep copy of the internal hash from our RequestStore. Keys are
|
188
|
+
# all symbols. Values are mostly primitives, but whodunnit can be a Proc.
|
189
|
+
# We cannot use Marshal.dump here because it doesn't support Proc. It is
|
190
|
+
# unclear exactly how `deep_dup` handles a Proc, but it doesn't complain.
|
191
|
+
# @api private
|
192
|
+
def to_h
|
193
|
+
store.deep_dup
|
194
|
+
end
|
195
|
+
|
196
|
+
# Provide a helpful error message if someone has a typo in one of their
|
197
|
+
# option keys. We don't validate option values here. That's traditionally
|
198
|
+
# been handled with casting (`to_s`, `!!`) in the accessor method.
|
199
|
+
# @api private
|
200
|
+
def validate_public_options(options)
|
201
|
+
options.each do |k, _v|
|
202
|
+
case k
|
203
|
+
when :controller_info, /enabled_for_/, :enabled, :whodunnit, :performance_mode, :performance_mode_data
|
204
|
+
next
|
205
|
+
when :transaction_id
|
206
|
+
raise ::SnailTrail::InvalidOption, "Cannot set private option: transaction_id"
|
207
|
+
else
|
208
|
+
raise InvalidOption, "Invalid option: #{k}"
|
209
|
+
end
|
175
210
|
end
|
176
211
|
end
|
177
|
-
end
|
178
212
|
end
|
179
213
|
end
|
180
214
|
end
|
@@ -35,15 +35,15 @@ module SnailTrail
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def creates
|
38
|
-
where event:
|
38
|
+
where event: %w[create batch_create]
|
39
39
|
end
|
40
40
|
|
41
41
|
def updates
|
42
|
-
where event:
|
42
|
+
where event: %w[update batch_update]
|
43
43
|
end
|
44
44
|
|
45
45
|
def destroys
|
46
|
-
where event:
|
46
|
+
where event: %w[destroy batch_destroy]
|
47
47
|
end
|
48
48
|
|
49
49
|
def not_creates
|
@@ -8,11 +8,11 @@ module SnailTrail
|
|
8
8
|
# People are encouraged to use `SnailTrail.gem_version` instead.
|
9
9
|
module VERSION
|
10
10
|
MAJOR = 1
|
11
|
-
MINOR =
|
11
|
+
MINOR = 1
|
12
12
|
TINY = 0
|
13
13
|
|
14
14
|
# Set PRE to nil unless it's a pre-release (beta, rc, etc.)
|
15
|
-
PRE =
|
15
|
+
PRE = 'rc.pre.1'
|
16
16
|
|
17
17
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".").freeze
|
18
18
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snail_trail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.1.0.rc.pre.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brands Insurance
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-05-
|
11
|
+
date: 2025-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -411,9 +411,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
411
411
|
version: 3.2.0
|
412
412
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
413
413
|
requirements:
|
414
|
-
- - "
|
414
|
+
- - ">"
|
415
415
|
- !ruby/object:Gem::Version
|
416
|
-
version:
|
416
|
+
version: 1.3.1
|
417
417
|
requirements: []
|
418
418
|
rubygems_version: 3.4.10
|
419
419
|
signing_key:
|