historiographer 4.1.9 → 4.1.10

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: e0a2f100a48aa0554022b2b53d7dd09cb296b298b6c6d92e6dae5b824cccd600
4
- data.tar.gz: 6472d913b3d16ae9b5adc2414d1bbc0eaab9d62f632d497e475fd35291b90999
3
+ metadata.gz: e211bf451d7041d58702ebc28a4485eb3a073978aca72ef1933e9b5dcebc49fe
4
+ data.tar.gz: 20ab524186b29a4c3dd44553a62b8853cf46a82aae4f139d18d3178b045cb35a
5
5
  SHA512:
6
- metadata.gz: c4dcc56d605f9c67ff7e00de652a9d180034e7c41c911d44e4c697a8843903a0da8669a7bf02a72877566835c5acc937f3a61c674dc206fc51e826720b9ff689
7
- data.tar.gz: c16605025d81e61edd43476e8c8b0e85035aacd496b071ab13cec7eeabc5469297b1342df7b3e352dfc8eee4999ee871361aebf6e16e324b0020733f02bf5cbc
6
+ metadata.gz: 055c01abfa33ab141ef48644ea38fa2a4052a9471d68519f89a659bbf45f83e37f66bb1aa847ba7014de9a46435af3cdced42d45ea122d25b70c409fdc312777
7
+ data.tar.gz: d7df91b900b2ea61b4e366b67972242d2882feadf8cfebbd8cd0d67875782535d267e084ec9cf044c835b4da757a0602b1ca8e75f6f27310faf4fe7b7bf69931
@@ -83,7 +83,6 @@ module Historiographer
83
83
 
84
84
  # Store the original class for method delegation
85
85
  class_variable_set(:@@original_class, foreign_class)
86
- class_variable_set(:@@method_map, {})
87
86
 
88
87
  #
89
88
  # A History class will be linked to the user
@@ -123,8 +122,6 @@ module Historiographer
123
122
  # Skip if we've already defined this method in the history class
124
123
  return if foreign_class.history_class.method_defined?(method_name)
125
124
 
126
- # Define the method in the history class
127
- foreign_class.history_class.set_method_map(method_name, false)
128
125
  foreign_class.history_class.class_eval do
129
126
  define_method(method_name) do |*args, &block|
130
127
  forward_method(method_name, *args, &block)
@@ -258,23 +255,6 @@ module Historiographer
258
255
  true
259
256
  end
260
257
 
261
- def method_added(method_name)
262
- set_method_map(method_name, true)
263
- end
264
-
265
- def set_method_map(method_name, is_overridden)
266
- mm = method_map
267
- mm[method_name.to_sym] = is_overridden
268
- class_variable_set(:@@method_map, mm)
269
- end
270
-
271
- def method_map
272
- unless class_variable_defined?(:@@method_map)
273
- class_variable_set(:@@method_map, {})
274
- end
275
- class_variable_get(:@@method_map) || {}
276
- end
277
-
278
258
  def original_class
279
259
  unless class_variable_defined?(:@@original_class)
280
260
  class_variable_set(:@@original_class, self.name.gsub(/History$/, '').constantize)
@@ -368,15 +348,19 @@ module Historiographer
368
348
  attrs[original_class.inheritance_column] = attrs[original_class.inheritance_column]&.gsub(/History$/, '')
369
349
  end
370
350
 
371
- # Create instance with all attributes except history-specific ones
372
- instance = original_class.instantiate(attrs.except(*cannot_keep_cols))
351
+ # Manually handle creating instance WITHOUT running find or initialize callbacks
352
+ # We will manually run callbacks below
353
+ # See: https://github.com/rails/rails/blob/95deab7b439abba23fdc4bd659116dab5dbe2606/activerecord/lib/active_record/core.rb#L487
354
+ #
355
+ attributes = original_class.attributes_builder.build_from_database(attrs.except(*cannot_keep_cols))
356
+ instance = original_class.allocate
373
357
 
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
358
+ # Set the internal attributes
359
+ instance.instance_variable_set(:@attributes, attributes)
360
+ instance.instance_variable_set(:@new_record, false)
361
+
362
+ # Initialize internal variables without triggering callbacks
363
+ instance.send(:init_internals)
380
364
 
381
365
  # Filter out any methods that are not overridden on the history class
382
366
  history_methods = self.class.instance_methods(false)
@@ -405,15 +389,13 @@ module Historiographer
405
389
  end
406
390
  end
407
391
 
408
- # Override class method to return history class
409
- instance.singleton_class.class_eval do
410
- define_method(:class) do
411
- history_instance = instance.instance_variable_get(:@_history_instance)
412
- history_instance.class
413
- end
392
+ instance.instance_variable_set(:@_history_instance, self)
393
+
394
+ if instance.send(original_class.primary_key).present?
395
+ instance.run_callbacks(:find)
414
396
  end
397
+ instance.run_callbacks(:initialize)
415
398
 
416
- instance.instance_variable_set(:@_history_instance, self)
417
399
  @dummy_instance = instance
418
400
  end
419
401
 
@@ -1,3 +1,3 @@
1
1
  module Historiographer
2
- VERSION = "4.1.9"
2
+ VERSION = "4.1.10"
3
3
  end
@@ -332,6 +332,10 @@ module Historiographer
332
332
  history_class = self.class.history_class
333
333
  foreign_key = history_class.history_foreign_key
334
334
 
335
+ attrs = attrs.stringify_keys
336
+ allowed_columns = self.class.columns.map(&:name)
337
+ attrs.select! { |k,v| allowed_columns.include?(k) }.to_h
338
+
335
339
  now ||= UTC.now
336
340
  attrs.merge!(foreign_key => attrs['id'], history_started_at: now, history_user_id: history_user_id)
337
341
  attrs.merge!(snapshot_id: snapshot_id) if snapshot_id.present?
@@ -343,6 +347,7 @@ module Historiographer
343
347
  end
344
348
 
345
349
  attrs = attrs.except('id')
350
+ attrs.stringify_keys!
346
351
 
347
352
  attrs
348
353
  end
@@ -361,6 +366,23 @@ module Historiographer
361
366
  raise HistoryUserIdMissingError, 'history_user_id must be passed in order to save record with histories! If you are in a context with no history_user_id, explicitly call #save_without_user'
362
367
  end
363
368
 
369
+ def list_callbacks(klass)
370
+ callbacks = {}
371
+
372
+ [:create, :update, :save, :destroy, :validation].each do |callback_type|
373
+ chain = klass.send("_#{callback_type}_callbacks")
374
+ callbacks[callback_type] = chain.map do |callback|
375
+ {
376
+ name: callback.filter,
377
+ kind: callback.kind,
378
+ options: callback.options
379
+ }
380
+ end
381
+ end
382
+
383
+ callbacks
384
+ end
385
+
364
386
  #
365
387
  # Save a record of the most recent changes, with the current
366
388
  # time as history_started_at, and the provided user as history_user_id.
@@ -375,9 +397,10 @@ module Historiographer
375
397
  current_history = histories.where(history_ended_at: nil).order('id desc').limit(1).last
376
398
 
377
399
  if history_class.history_foreign_key.present? && history_class.present?
378
- instance = history_class.new(attrs)
379
- instance.save(validate: false)
380
- current_history.update!(history_ended_at: now) if current_history.present?
400
+ result = history_class.insert_all([attrs])
401
+ inserted_id = result.rows.first.first if history_class.primary_key == 'id'
402
+ instance = history_class.find(inserted_id)
403
+ current_history.update_columns(history_ended_at: now) if current_history.present?
381
404
  instance
382
405
  else
383
406
  raise 'Need foreign key and history class to save history!'
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.9
4
+ version: 4.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - brettshollenberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-03 00:00:00.000000000 Z
11
+ date: 2024-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord