historiographer 4.1.9 → 4.1.10

Sign up to get free protection for your applications and to get access to all the features.
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