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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28891ab31232a7eae8efccd015269069d992eb775259c6a6b9e738da1df69aed
4
- data.tar.gz: 7a794f1a26351b47d194a0b8d18eb0222d49e9dd7d2b6cdcf90467d94cea62b0
3
+ metadata.gz: e0a2f100a48aa0554022b2b53d7dd09cb296b298b6c6d92e6dae5b824cccd600
4
+ data.tar.gz: 6472d913b3d16ae9b5adc2414d1bbc0eaab9d62f632d497e475fd35291b90999
5
5
  SHA512:
6
- metadata.gz: 16ee4305c1aa8c6f09a13b042185afceea10fd18c0a19f7dba360bcab65a7f1a270dce78e24f15f2a30806fa4f4bcdf5ea6c10ecb81060b3dca02724918d7f5e
7
- data.tar.gz: e66e7f2a31b5f65689f112ae6b43adeff5e286c42aeb6ed2ffc8931e1a75426dac3f4cb615b2fc06a537c74f070f4f2a245fe4668be8814b8382bd5084336651
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
- instance = original_class.find_or_initialize_by(original_class.primary_key => attrs[original_class.primary_key])
355
- instance.assign_attributes(attrs.except(*cannot_keep_cols))
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
@@ -1,3 +1,3 @@
1
1
  module Historiographer
2
- VERSION = "4.1.8"
2
+ VERSION = "4.1.9"
3
3
  end
@@ -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.create!(attrs).tap do |new_history|
379
- current_history.update!(history_ended_at: now) if current_history.present?
380
- end
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.8
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-30 00:00:00.000000000 Z
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