Class: ActiveSnapshotRails::Snapshot

Inherits:
Object
  • Object
show all
Defined in:
lib/active_snapshot_rails.rb

Class Method Summary collapse

Class Method Details

.capture_associations(record, associations) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/active_snapshot_rails.rb', line 33

def self.capture_associations(record, associations)
  association_data = {}

  associations.each do |association|
    nested_associations = []
    
    if association.is_a?(Hash)
      association_name = association.keys.first
      nested_associations = association.values.flatten
    else
      association_name = association
    end

    if record.respond_to?(association_name)
      related_records = record.send(association_name)
      
      if related_records.is_a?(ActiveRecord::Base)
        association_data[association_name] = {
          attributes: related_records.attributes,
          associations: capture_associations(related_records, nested_associations)
        }
      elsif related_records.respond_to?(:map)
        association_data[association_name] = related_records.map do |related_record|
          {
            attributes: related_record.attributes,
            associations: capture_associations(related_record, nested_associations)
          }
        end
      end
    end
  end

  association_data
end

.restore(record, snapshot_file) ⇒ Object

Raises:

  • (ArgumentError)


19
20
21
22
23
24
25
26
27
28
29
# File 'lib/active_snapshot_rails.rb', line 19

def self.restore(record, snapshot_file)
  snapshot_data = JSON.parse(File.read(snapshot_file))

  raise ArgumentError, "Snapshot file does not match the given record" unless snapshot_data["record_id"] == record.id

  # Restore record attributes
  record.update!(snapshot_data["attributes"])

  # Restore associations
  restore_associations(record, snapshot_data["associations"])
end

.restore_associations(record, associations_data) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/active_snapshot_rails.rb', line 68

def self.restore_associations(record, associations_data)
  associations_data.each do |association_name, related_data|
    if related_data.is_a?(Array)
      # Restore has_many associations
      associated_class = record.class.reflect_on_association(association_name).klass
      record.send(association_name).destroy_all

      related_data.each do |related_record_data|
        associated_record = associated_class.create!(related_record_data["attributes"])
        restore_associations(associated_record, related_record_data["associations"])
      end
    else
      # Restore belongs_to or has_one association
      associated_class = record.class.reflect_on_association(association_name).klass
      associated_record = associated_class.create!(related_data["attributes"])
      restore_associations(associated_record, related_data["associations"])
    end
  end
end

.take(record, include_associations: [], name: nil) ⇒ Object

Raises:

  • (ArgumentError)


6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/active_snapshot_rails.rb', line 6

def self.take(record, include_associations: [], name: nil)
  raise ArgumentError, "Record must be an ActiveRecord::Base instance" unless record.is_a?(ActiveRecord::Base)

  snapshot_data = {
    model: record.class.name,
    record_id: record.id,
    attributes: record.attributes,
    associations: capture_associations(record, include_associations)
  }

  SnapshotStorage.save_snapshot(record, snapshot_data, name)
end