historiographer 4.1.8 → 4.1.9
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/historiographer/history.rb +39 -15
- data/lib/historiographer/version.rb +1 -1
- data/lib/historiographer.rb +4 -3
- metadata +2 -3
- data/lib/historiographer/history/instance_methods.rb +0 -98
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0a2f100a48aa0554022b2b53d7dd09cb296b298b6c6d92e6dae5b824cccd600
|
4
|
+
data.tar.gz: 6472d913b3d16ae9b5adc2414d1bbc0eaab9d62f632d497e475fd35291b90999
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4dcc56d605f9c67ff7e00de652a9d180034e7c41c911d44e4c697a8843903a0da8669a7bf02a72877566835c5acc937f3a61c674dc206fc51e826720b9ff689
|
7
|
+
data.tar.gz: c16605025d81e61edd43476e8c8b0e85035aacd496b071ab13cec7eeabc5469297b1342df7b3e352dfc8eee4999ee871361aebf6e16e324b0020733f02bf5cbc
|
@@ -69,17 +69,6 @@ module Historiographer
|
|
69
69
|
#
|
70
70
|
scope :current, -> { where(history_ended_at: nil).order(id: :desc) }
|
71
71
|
|
72
|
-
#
|
73
|
-
# A History class will be linked to the user
|
74
|
-
# that made the changes.
|
75
|
-
#
|
76
|
-
# E.g.
|
77
|
-
#
|
78
|
-
# RetailerProductHistory.first.user
|
79
|
-
#
|
80
|
-
# To use histories, a user class must be defined.
|
81
|
-
#
|
82
|
-
belongs_to :user, foreign_key: :history_user_id
|
83
72
|
|
84
73
|
#
|
85
74
|
# Historiographer is opinionated about how History classes
|
@@ -96,6 +85,20 @@ module Historiographer
|
|
96
85
|
class_variable_set(:@@original_class, foreign_class)
|
97
86
|
class_variable_set(:@@method_map, {})
|
98
87
|
|
88
|
+
#
|
89
|
+
# A History class will be linked to the user
|
90
|
+
# that made the changes.
|
91
|
+
#
|
92
|
+
# E.g.
|
93
|
+
#
|
94
|
+
# RetailerProductHistory.first.user
|
95
|
+
#
|
96
|
+
# To use histories, a user class must be defined.
|
97
|
+
#
|
98
|
+
unless foreign_class.ancestors.include?(Historiographer::Silent)
|
99
|
+
belongs_to :user, foreign_key: :history_user_id
|
100
|
+
end
|
101
|
+
|
99
102
|
# Add method_added hook to the original class
|
100
103
|
foreign_class.singleton_class.class_eval do
|
101
104
|
# Keep track of original method_added if it exists
|
@@ -244,9 +247,17 @@ module Historiographer
|
|
244
247
|
raise "Cannot snapshot a history model!"
|
245
248
|
end
|
246
249
|
|
250
|
+
def is_history_class?
|
251
|
+
true
|
252
|
+
end
|
253
|
+
|
247
254
|
end
|
248
255
|
|
249
256
|
class_methods do
|
257
|
+
def is_history_class?
|
258
|
+
true
|
259
|
+
end
|
260
|
+
|
250
261
|
def method_added(method_name)
|
251
262
|
set_method_map(method_name, true)
|
252
263
|
end
|
@@ -311,6 +322,7 @@ module Historiographer
|
|
311
322
|
has_many assoc_name, scope, class_name: assoc_class_name, foreign_key: assoc_foreign_key, primary_key: history_foreign_key
|
312
323
|
end
|
313
324
|
end
|
325
|
+
|
314
326
|
#
|
315
327
|
# The foreign key to the primary class.
|
316
328
|
#
|
@@ -343,20 +355,32 @@ module Historiographer
|
|
343
355
|
def dummy_instance
|
344
356
|
return @dummy_instance if @dummy_instance
|
345
357
|
|
358
|
+
# Only exclude history-specific columns
|
346
359
|
cannot_keep_cols = %w(history_started_at history_ended_at history_user_id snapshot_id)
|
347
|
-
cannot_keep_cols += [self.class.inheritance_column.to_sym] if self.original_class.sti_enabled?
|
348
360
|
cannot_keep_cols += [self.class.history_foreign_key]
|
349
361
|
cannot_keep_cols.map!(&:to_s)
|
350
362
|
|
351
363
|
attrs = attributes.clone
|
352
364
|
attrs[original_class.primary_key] = attrs[self.class.history_foreign_key]
|
353
365
|
|
354
|
-
|
355
|
-
|
366
|
+
if original_class.sti_enabled?
|
367
|
+
# Remove History suffix from type if present
|
368
|
+
attrs[original_class.inheritance_column] = attrs[original_class.inheritance_column]&.gsub(/History$/, '')
|
369
|
+
end
|
370
|
+
|
371
|
+
# Create instance with all attributes except history-specific ones
|
372
|
+
instance = original_class.instantiate(attrs.except(*cannot_keep_cols))
|
373
|
+
|
374
|
+
if instance.valid?
|
375
|
+
if instance.send(original_class.primary_key).present?
|
376
|
+
instance.run_callbacks(:find)
|
377
|
+
end
|
378
|
+
instance.run_callbacks(:initialize)
|
379
|
+
end
|
356
380
|
|
357
381
|
# Filter out any methods that are not overridden on the history class
|
358
382
|
history_methods = self.class.instance_methods(false)
|
359
|
-
history_class_location = Module.const_source_location(self.class.name).first
|
383
|
+
history_class_location = Module.const_source_location(self.class.name).first
|
360
384
|
history_methods.select! do |method|
|
361
385
|
self.class.instance_method(method).source_location.first == history_class_location
|
362
386
|
end
|
data/lib/historiographer.rb
CHANGED
@@ -375,9 +375,10 @@ module Historiographer
|
|
375
375
|
current_history = histories.where(history_ended_at: nil).order('id desc').limit(1).last
|
376
376
|
|
377
377
|
if history_class.history_foreign_key.present? && history_class.present?
|
378
|
-
history_class.
|
379
|
-
|
380
|
-
|
378
|
+
instance = history_class.new(attrs)
|
379
|
+
instance.save(validate: false)
|
380
|
+
current_history.update!(history_ended_at: now) if current_history.present?
|
381
|
+
instance
|
381
382
|
else
|
382
383
|
raise 'Need foreign key and history class to save history!'
|
383
384
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: historiographer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.
|
4
|
+
version: 4.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- brettshollenberger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -247,7 +247,6 @@ files:
|
|
247
247
|
- lib/historiographer.rb
|
248
248
|
- lib/historiographer/configuration.rb
|
249
249
|
- lib/historiographer/history.rb
|
250
|
-
- lib/historiographer/history/instance_methods.rb
|
251
250
|
- lib/historiographer/history_migration.rb
|
252
251
|
- lib/historiographer/history_migration_mysql.rb
|
253
252
|
- lib/historiographer/mysql_migration.rb
|
@@ -1,98 +0,0 @@
|
|
1
|
-
module Historiographer
|
2
|
-
module History
|
3
|
-
module InstanceMethods
|
4
|
-
def destroy
|
5
|
-
false
|
6
|
-
end
|
7
|
-
|
8
|
-
def destroy!
|
9
|
-
false
|
10
|
-
end
|
11
|
-
|
12
|
-
def save(*args, **kwargs)
|
13
|
-
if persisted? && (changes.keys - %w(history_ended_at snapshot_id)).any?
|
14
|
-
false
|
15
|
-
else
|
16
|
-
super(*args, **kwargs)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def save!(*args, **kwargs)
|
21
|
-
if persisted? && (changes.keys - %w(history_ended_at snapshot_id)).any?
|
22
|
-
false
|
23
|
-
else
|
24
|
-
super(*args, **kwargs)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def snapshot
|
29
|
-
raise "Cannot snapshot a history model!"
|
30
|
-
end
|
31
|
-
|
32
|
-
def original_class
|
33
|
-
self.class.original_class
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def dummy_instance
|
39
|
-
return @dummy_instance if @dummy_instance
|
40
|
-
|
41
|
-
cannot_keep_cols = %w(history_started_at history_ended_at history_user_id snapshot_id)
|
42
|
-
cannot_keep_cols += [self.class.inheritance_column.to_sym] if self.original_class.sti_enabled?
|
43
|
-
cannot_keep_cols += [self.class.history_foreign_key]
|
44
|
-
cannot_keep_cols.map!(&:to_s)
|
45
|
-
|
46
|
-
attrs = attributes.clone
|
47
|
-
attrs[original_class.primary_key] = attrs[self.class.history_foreign_key]
|
48
|
-
|
49
|
-
instance = original_class.find_or_initialize_by(original_class.primary_key => attrs[original_class.primary_key])
|
50
|
-
instance.assign_attributes(attrs.except(*cannot_keep_cols))
|
51
|
-
|
52
|
-
# Create a module to hold methods from the history class
|
53
|
-
history_methods_module = Module.new
|
54
|
-
|
55
|
-
# Get methods defined directly in the history class, excluding baseline methods
|
56
|
-
history_methods = self.class.instance_methods(false) - baseline_methods
|
57
|
-
|
58
|
-
history_methods.each do |method_name|
|
59
|
-
next if instance.singleton_class.method_defined?(method_name)
|
60
|
-
|
61
|
-
method = self.class.instance_method(method_name)
|
62
|
-
history_methods_module.define_method(method_name) do |*args, &block|
|
63
|
-
method.bind(self.instance_variable_get(:@_history_instance)).call(*args, &block)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
instance.singleton_class.prepend(history_methods_module)
|
68
|
-
|
69
|
-
self.class.reflect_on_all_associations.each do |reflection|
|
70
|
-
instance.singleton_class.class_eval do
|
71
|
-
define_method(reflection.name) do |*args, &block|
|
72
|
-
history_instance = instance.instance_variable_get(:@_history_instance)
|
73
|
-
history_instance.send(reflection.name, *args, &block)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
instance.singleton_class.class_eval do
|
79
|
-
define_method(:class) do
|
80
|
-
history_instance = instance.instance_variable_get(:@_history_instance)
|
81
|
-
history_instance.class
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
instance.instance_variable_set(:@_history_instance, self)
|
86
|
-
@dummy_instance = instance
|
87
|
-
end
|
88
|
-
|
89
|
-
def forward_method(method_name, *args, &block)
|
90
|
-
if method_name == :class || method_name == 'class'
|
91
|
-
self.class
|
92
|
-
else
|
93
|
-
dummy_instance.send(method_name, *args, &block)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|