snapshotable 0.0.2 → 0.0.3

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
  SHA1:
3
- metadata.gz: acbed2ff58337c9ea062a66e6903534f8c438a38
4
- data.tar.gz: b673bec953e6067fe9baacc1447be0fa07109fcf
3
+ metadata.gz: 295739bcb71078e20aa642a39b554663b3eba3ed
4
+ data.tar.gz: 1aa27734ea1eceb4f18ef96e251cde73cc2b87a4
5
5
  SHA512:
6
- metadata.gz: 455c66dc663627512c89ec58a74e0c3be63b3a470e140a0ef3a32ca66f6fb952e2415eabae0a223c1378a70d232a0e06b963013e599a1f922fb84988ee8dda80
7
- data.tar.gz: 4f7b81e9cb19139b243a62e7cb0ec8a1d27539f980ec3752b37ed6b8cac7b97493a8598a8643b646f230f2cc7a36b14fbe81d4f2c37ef45db0178385c475c9fd
6
+ metadata.gz: e26506fecd06d327690dcda5a88a9a1ef557b3153e47bf4ca93ffd2b1fc95bb61dd3e657f2ef2c36325dcd9adda7c793975832ec8067a9a7ef1a49a45c1cfd4a
7
+ data.tar.gz: 5b6084efc5ff846800c97689f2cc8d3f28e05cf21cf86ea5a9bf53ce42572198763928bf7137cddef87c22b8cfd9e74b9bcfed4363397a9765833bdeb00ac612
data/README.md CHANGED
@@ -95,11 +95,7 @@ In this case, the model won't change, but you could modify it manually if you wi
95
95
 
96
96
  ### Setting the base model
97
97
 
98
- After creating the Snapshot model, add a `has_many` relation to the base model
99
- ```
100
- has_many user_snapshots, dependent: :destroy
101
- ```
102
- Then, set which attributes should be saved on the Snapshot using `snapshot` on the model
98
+ Set which attributes should be saved on the Snapshot using `snapshot` on the model
103
99
  ```
104
100
  snapshot :id, :name, :age, profile: [:description], photo: [:url], groups: [:name], friends: [:name, :age]
105
101
  ```
@@ -17,7 +17,7 @@ module Snapshotable
17
17
  def snapshot_attrs
18
18
  snapshot = {}
19
19
 
20
- add_custom_attributes(snapshot) if custom_snapshot_attributes.any?
20
+ add_custom_attributes(snapshot) if custom_snapshot_attributes&.any?
21
21
 
22
22
  snapshot[:object] = extract_attributes(record_snapshot_attrs, record) if record_snapshot_attrs.any?
23
23
 
@@ -27,7 +27,7 @@ module Snapshotable
27
27
  end
28
28
 
29
29
  def add_custom_attributes(snapshot)
30
- record.custom_snapshot_attributes.each do |key, attribute|
30
+ custom_snapshot_attributes.each do |key, attribute|
31
31
  snapshot[key] = record.send(attribute)
32
32
  end
33
33
  end
@@ -53,15 +53,15 @@ module Snapshotable
53
53
  end
54
54
 
55
55
  def record_snapshot_attrs
56
- @record_snapshot_attrs ||= record.attributes_to_save_on_snapshot.select { |attr| attr.is_a? Symbol }
56
+ @record_snapshot_attrs ||= record.class.attributes_to_save_on_snapshot.select { |attr| attr.is_a? Symbol }
57
57
  end
58
58
 
59
59
  def deep_snapshot_attrs
60
- @deep_snapshot_attrs ||= record.attributes_to_save_on_snapshot.select { |attr| attr.is_a? Hash }.first
60
+ @deep_snapshot_attrs ||= record.class.attributes_to_save_on_snapshot.select { |attr| attr.is_a? Hash }.first
61
61
  end
62
62
 
63
63
  def custom_snapshot_attributes
64
- @custom_snapshot_attributes ||= record.custom_snapshot_attributes
64
+ @custom_snapshot_attributes ||= record.class.custom_snapshot_attributes.first
65
65
  end
66
66
  end
67
67
  end
data/lib/snapshotable.rb CHANGED
@@ -1,70 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'services/snapshot_creator'
3
+ require 'snapshotable/snapshots'
4
4
 
5
5
  module Snapshotable
6
- # rubocop:disable Metrics/AbcSize
7
- # rubocop:disable Metrics/MethodLength
8
- # rubocop:disable Metrics/BlockLength
9
- def self.included(base)
10
- base.class_eval do
11
- extend ClassMethods
12
- class_attribute :attributes_to_save_on_snapshot, instance_writer: false
13
- class_attribute :attributes_to_ignore_on_diff, instance_writer: false
14
- class_attribute :custom_snapshot_attributes, instance_writer: false
15
-
16
- self.attributes_to_save_on_snapshot = []
17
- self.attributes_to_ignore_on_diff = %w[id created_at updated_at]
18
- self.custom_snapshot_attributes = {}
19
-
20
- unless instance_methods.include?(:take_snapshot!)
21
- def take_snapshot!
22
- snapshot = SnapshotCreator.new(self).call
23
- snapshot_model = Object.const_get("#{self.class.name}Snapshot")
24
-
25
- snapshot_model.create!(snapshot) if should_create_new_snapshot?(snapshot)
26
- end
27
- end
28
-
29
- unless instance_methods.include?(:last_snapshot)
30
- def last_snapshot
31
- send("#{self.class.name.downcase}_snapshots").last
32
- end
33
- end
34
-
35
- unless instance_methods.include?(:should_create_cache?)
36
- def should_create_new_snapshot?(snapshot)
37
- return true if last_snapshot.nil?
38
-
39
- snapshot_to_compare = last_snapshot
40
- .attributes
41
- .except(*attributes_to_ignore_on_diff)
42
- .with_indifferent_access
43
-
44
- HashDiff.diff(snapshot_to_compare, snapshot.with_indifferent_access).any?
45
- end
46
- end
47
- end
48
- end
49
- # rubocop:enable Metrics/AbcSize
50
- # rubocop:enable Metrics/MethodLength
51
- # rubocop:enable Metrics/BlockLength
52
-
53
- module ClassMethods
54
- def snapshot(*attributes)
55
- self.attributes_to_save_on_snapshot = attributes
56
- end
57
-
58
- def snapshot_ignore_diff(*attributes)
59
- self.attributes_to_ignore_on_diff = attributes.map(&:to_s)
6
+ class << self
7
+ # Switches Snapshotable on or off
8
+ def enabled=(value)
9
+ Snapshotable.config.enabled = value
60
10
  end
61
11
 
62
- def custom_snapshot(*attributes)
63
- self.custom_snapshot_attributes = attributes.first
12
+ # Returns if Snapshotable is turned on
13
+ def enabled?
14
+ Snapshotable.config.enabled.present?
64
15
  end
65
16
  end
66
17
  end
67
18
 
68
19
  ActiveSupport.on_load :active_record do
69
- include Snapshotable
20
+ include Snapshotable::Model
70
21
  end
@@ -0,0 +1,84 @@
1
+ module Snapshotable
2
+ class ModelConfig
3
+ DEFAULT_ATTRIBUTES = [].freeze
4
+ DEFAULT_IGNORE_ATTRIBUTES = %w[id created_at updated_at].freeze
5
+ DEFAULT_CUSTOM_ATTRIBUTES = {}.freeze
6
+
7
+ def initialize(model)
8
+ @model = model
9
+ end
10
+
11
+ def setup_snapshot
12
+ setup_snapshot_names
13
+ setup_variables
14
+ setup_association(@model)
15
+
16
+ @model.send :include, ::Snapshotable::Model::InstanceMethods
17
+ end
18
+
19
+ def setup_snapshot_attributes(attributes)
20
+ setup_snapshot unless snapshot_configured?
21
+ @model.attributes_to_save_on_snapshot = attributes || DEFAULT_ATTRIBUTES
22
+ end
23
+
24
+ def setup_snapshot_ignore(attributes)
25
+ setup_snapshot unless snapshot_configured?
26
+ @model.attributes_to_ignore_on_diff = attributes || DEFAULT_IGNORE_ATTRIBUTES
27
+ end
28
+
29
+ def setup_snapshot_custom(attributes)
30
+ setup_snapshot unless snapshot_configured?
31
+ @model.custom_snapshot_attributes = attributes || DEFAULT_CUSTOM_ATTRIBUTES
32
+ end
33
+
34
+ def snapshot_configured?
35
+ @model.respond_to?(:snapshot_configured) && @model.snapshot_configured
36
+ end
37
+
38
+ def setup_variables
39
+ @model.class_attribute :attributes_to_save_on_snapshot, instance_writer: false
40
+ @model.attributes_to_save_on_snapshot = DEFAULT_ATTRIBUTES
41
+ @model.send :attr_accessor, :attributes_to_save_on_snapshot
42
+
43
+ @model.class_attribute :attributes_to_ignore_on_diff, instance_writer: false
44
+ @model.attributes_to_ignore_on_diff = DEFAULT_IGNORE_ATTRIBUTES
45
+ @model.send :attr_accessor, :attributes_to_ignore_on_diff
46
+
47
+ @model.class_attribute :custom_snapshot_attributes, instance_writer: false
48
+ @model.custom_snapshot_attributes = DEFAULT_CUSTOM_ATTRIBUTES
49
+ @model.send :attr_accessor, :custom_snapshot_attributes
50
+
51
+ @model.class_attribute :snapshot_configured
52
+ @model.snapshot_configured = true
53
+ @model.send :attr_accessor, :snapshot_configured
54
+ end
55
+
56
+ def setup_snapshot_names
57
+ @model.class_attribute :snapshot_association_name
58
+ @model.snapshot_association_name = snapshot_association_name
59
+
60
+ @model.class_attribute :snapshot_class_name
61
+ @model.snapshot_class_name = snapshot_class_name
62
+ end
63
+
64
+ def setup_association(klass)
65
+ klass.has_many(
66
+ klass.snapshot_association_name,
67
+ class_name: klass.snapshot_class_name,
68
+ dependent: :destroy
69
+ )
70
+ end
71
+
72
+ def snapshot_class_name
73
+ "#{@model.name}Snapshot"
74
+ end
75
+
76
+ def snapshot_association_name
77
+ snapshot_class_name.pluralize.underscore.to_sym
78
+ end
79
+
80
+ def snapshot_foreign_key
81
+ "#{@model.name.downcase}_id"
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'services/snapshot_creator'
4
+ require 'snapshotable/model_config'
5
+
6
+ module Snapshotable
7
+ module Model
8
+ def self.included(base)
9
+ base.send :extend, ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ def snapshot(*attributes)
14
+ snapshotable_config.setup_snapshot_attributes(attributes)
15
+ end
16
+
17
+ def snapshot_ignore_diff(*attributes)
18
+ snapshotable_config.setup_snapshot_ignore(attributes)
19
+ end
20
+
21
+ def custom_snapshot(*attributes)
22
+ snapshotable_config.setup_snapshot_custom(attributes)
23
+ end
24
+
25
+ def snapshotable_config
26
+ ::Snapshotable::ModelConfig.new(self)
27
+ end
28
+ end
29
+
30
+ module InstanceMethods
31
+ def take_snapshot!
32
+ snapshot = SnapshotCreator.new(self).call
33
+ snapshot_class.create!(snapshot) if should_create_new_snapshot?(snapshot)
34
+ end
35
+
36
+ def snapshots
37
+ send(snapshot_association_name)
38
+ end
39
+
40
+ def snapshot_class
41
+ Object.const_get(snapshot_class_name)
42
+ end
43
+
44
+ def should_create_new_snapshot?(snapshot)
45
+ last_snapshot = snapshots.last
46
+ return true if last_snapshot.nil?
47
+
48
+ snapshot_to_compare = last_snapshot
49
+ .attributes
50
+ .except(*self.class.attributes_to_ignore_on_diff)
51
+ .with_indifferent_access
52
+
53
+ HashDiff.diff(snapshot_to_compare, snapshot.with_indifferent_access).any?
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Snapshotable
4
- VERSION = '0.0.2'.freeze
4
+ VERSION = '0.0.3'.freeze
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snapshotable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - João Batista Marinho
@@ -166,6 +166,8 @@ files:
166
166
  - lib/generators/snapshotable/templates/model.rb
167
167
  - lib/services/snapshot_creator.rb
168
168
  - lib/snapshotable.rb
169
+ - lib/snapshotable/model_config.rb
170
+ - lib/snapshotable/snapshots.rb
169
171
  - lib/snapshotable/version.rb
170
172
  - lib/tasks/cacheable_models.rake
171
173
  homepage: https://github.com/QultureRocks/snapshotable