snapshotable 0.0.1 → 0.0.2
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 +4 -4
- data/README.md +13 -13
- data/lib/generators/snapshotable/create_generator.rb +15 -15
- data/lib/generators/snapshotable/templates/migration.rb +2 -2
- data/lib/services/snapshot_creator.rb +23 -9
- data/lib/snapshotable/version.rb +3 -1
- data/lib/snapshotable.rb +8 -0
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acbed2ff58337c9ea062a66e6903534f8c438a38
|
4
|
+
data.tar.gz: b673bec953e6067fe9baacc1447be0fa07109fcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 455c66dc663627512c89ec58a74e0c3be63b3a470e140a0ef3a32ca66f6fb952e2415eabae0a223c1378a70d232a0e06b963013e599a1f922fb84988ee8dda80
|
7
|
+
data.tar.gz: 4f7b81e9cb19139b243a62e7cb0ec8a1d27539f980ec3752b37ed6b8cac7b97493a8598a8643b646f230f2cc7a36b14fbe81d4f2c37ef45db0178385c475c9fd
|
data/README.md
CHANGED
@@ -41,8 +41,8 @@ class CreateContractSnapshots < ActiveRecord::Migration
|
|
41
41
|
# model to be snapshoted
|
42
42
|
t.references :user, index: true, null: false, foreign_key: true
|
43
43
|
|
44
|
-
#
|
45
|
-
t.jsonb :
|
44
|
+
# snapshoted_object
|
45
|
+
t.jsonb :object, null: false
|
46
46
|
t.timestamps null: false
|
47
47
|
end
|
48
48
|
end
|
@@ -55,7 +55,7 @@ class UserSnapshot < ApplicationRecord
|
|
55
55
|
belongs_to :user
|
56
56
|
|
57
57
|
validates :user, presence: true
|
58
|
-
validates :
|
58
|
+
validates :object, presence: true
|
59
59
|
end
|
60
60
|
```
|
61
61
|
|
@@ -77,13 +77,13 @@ class CreateContractSnapshots < ActiveRecord::Migration
|
|
77
77
|
t.references :user, index: true, null: false, foreign_key: true
|
78
78
|
|
79
79
|
# snapshoted_attributes
|
80
|
-
t.jsonb :
|
80
|
+
t.jsonb :object, null: false
|
81
81
|
|
82
|
-
t.jsonb :
|
83
|
-
t.jsonb :
|
82
|
+
t.jsonb :profile_object, null: false
|
83
|
+
t.jsonb :photo_object, null: false
|
84
84
|
|
85
|
-
t.jsonb :
|
86
|
-
t.jsonb :
|
85
|
+
t.jsonb :groups_object, null: false, array: true, default: []
|
86
|
+
t.jsonb :friends_object, null: false, array: true, default: []
|
87
87
|
|
88
88
|
t.timestamps null: false
|
89
89
|
end
|
@@ -112,24 +112,24 @@ In the example above a `UserSnapshot` would be created like this:
|
|
112
112
|
```
|
113
113
|
{
|
114
114
|
user_id: user.id,
|
115
|
-
|
115
|
+
object: {
|
116
116
|
id: user.id,
|
117
117
|
name: user.name,
|
118
118
|
age: user.age
|
119
119
|
},
|
120
|
-
|
120
|
+
profile_object: {
|
121
121
|
description: user.profile.description
|
122
122
|
},
|
123
|
-
|
123
|
+
photo_object: {
|
124
124
|
url: user.photo.url
|
125
125
|
},
|
126
|
-
|
126
|
+
groups_object: [{
|
127
127
|
name: user.groups.first.name
|
128
128
|
},
|
129
129
|
{
|
130
130
|
name: user.groups.second.name
|
131
131
|
}],
|
132
|
-
|
132
|
+
friends_object: [{
|
133
133
|
name: user.friends.first.name,
|
134
134
|
age: user.friends.first.age
|
135
135
|
},
|
@@ -1,49 +1,49 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators'
|
4
|
+
require 'rails/generators/migration'
|
5
|
+
require 'active_record'
|
6
|
+
require 'rails/generators/active_record'
|
5
7
|
|
6
8
|
module Snapshotable
|
7
9
|
module Generators
|
8
10
|
class CreateGenerator < Rails::Generators::Base
|
9
11
|
include Rails::Generators::Migration
|
10
12
|
|
11
|
-
source_root File.expand_path(
|
13
|
+
source_root File.expand_path('templates', __dir__)
|
12
14
|
|
13
15
|
argument :snapshotable_model, type: :string
|
14
16
|
class_option :has_one, type: :array, default: [], desc: 'has_one relations to add to the snapshot'
|
15
17
|
class_option :has_many, type: :array, default: [], desc: 'has_many relations to add to the snapshot'
|
16
18
|
|
17
19
|
def generate_migration_and_model
|
18
|
-
migration_template
|
19
|
-
template
|
20
|
+
migration_template 'migration.rb', "db/migrate/create_#{snapshotable_model}_snapshots.rb", migration_version: migration_version
|
21
|
+
template 'model.rb', "app/models/#{model_underscored}_snapshot.rb"
|
20
22
|
end
|
21
23
|
|
22
24
|
# Implement the required interface for Rails::Generators::Migration.
|
23
25
|
def self.next_migration_number(dirname) #:nodoc:
|
24
26
|
next_migration_number = current_migration_number(dirname) + 1
|
25
27
|
if ActiveRecord::Base.timestamped_migrations
|
26
|
-
[Time.now.utc.strftime(
|
28
|
+
[Time.now.utc.strftime('%Y%m%d%H%M%S'), format('%.14d', next_migration_number)].max
|
27
29
|
else
|
28
|
-
|
30
|
+
format('%.3d', next_migration_number)
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
34
|
def migration_version
|
33
|
-
if ActiveRecord::VERSION::MAJOR >= 5
|
34
|
-
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
35
|
-
end
|
35
|
+
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]" if ActiveRecord::VERSION::MAJOR >= 5
|
36
36
|
end
|
37
37
|
|
38
38
|
def active_record_class
|
39
39
|
ActiveRecord::VERSION::MAJOR >= 5 ? 'ApplicationRecord' : 'ActiveRecord::Base'
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
42
|
+
def relations_has_one
|
43
43
|
options['has_one']
|
44
44
|
end
|
45
45
|
|
46
|
-
def
|
46
|
+
def relations_has_many
|
47
47
|
options['has_many']
|
48
48
|
end
|
49
49
|
|
@@ -56,4 +56,4 @@ module Snapshotable
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
59
|
-
end
|
59
|
+
end
|
@@ -6,9 +6,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
|
|
6
6
|
|
7
7
|
# snapshoted_attributes
|
8
8
|
t.jsonb :attributes, null: false
|
9
|
-
<%
|
9
|
+
<% relations_has_one.each do |relation| %>
|
10
10
|
t.jsonb :<%= relation.underscore %>_attributes, null: false<% end %>
|
11
|
-
<%
|
11
|
+
<% relations_has_many.each do |relation| %>
|
12
12
|
t.jsonb :<%= relation.underscore %>_attributes, null: false, array: true, default: []<% end %>
|
13
13
|
|
14
14
|
t.timestamps null: false
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Snapshotable
|
2
4
|
class SnapshotCreator
|
3
5
|
def initialize(record)
|
@@ -15,23 +17,31 @@ module Snapshotable
|
|
15
17
|
def snapshot_attrs
|
16
18
|
snapshot = {}
|
17
19
|
|
20
|
+
add_custom_attributes(snapshot) if custom_snapshot_attributes.any?
|
21
|
+
|
22
|
+
snapshot[:object] = extract_attributes(record_snapshot_attrs, record) if record_snapshot_attrs.any?
|
23
|
+
|
24
|
+
add_deep_snapshot_objects(snapshot)
|
25
|
+
|
26
|
+
snapshot
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_custom_attributes(snapshot)
|
18
30
|
record.custom_snapshot_attributes.each do |key, attribute|
|
19
31
|
snapshot[key] = record.send(attribute)
|
20
32
|
end
|
33
|
+
end
|
21
34
|
|
22
|
-
|
23
|
-
|
35
|
+
def add_deep_snapshot_objects(snapshot)
|
24
36
|
deep_snapshot_attrs&.each do |association_name, attributes|
|
25
37
|
association = record.send(association_name)
|
26
38
|
|
27
|
-
snapshot["#{association_name}
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
39
|
+
snapshot["#{association_name}_object"] = if association.class.name == 'ActiveRecord::Associations::CollectionProxy'
|
40
|
+
association.map { |model| extract_attributes(attributes, model) }
|
41
|
+
else
|
42
|
+
extract_attributes(attributes, association)
|
43
|
+
end
|
32
44
|
end
|
33
|
-
|
34
|
-
snapshot
|
35
45
|
end
|
36
46
|
|
37
47
|
def extract_attributes(attributes, model)
|
@@ -49,5 +59,9 @@ module Snapshotable
|
|
49
59
|
def deep_snapshot_attrs
|
50
60
|
@deep_snapshot_attrs ||= record.attributes_to_save_on_snapshot.select { |attr| attr.is_a? Hash }.first
|
51
61
|
end
|
62
|
+
|
63
|
+
def custom_snapshot_attributes
|
64
|
+
@custom_snapshot_attributes ||= record.custom_snapshot_attributes
|
65
|
+
end
|
52
66
|
end
|
53
67
|
end
|
data/lib/snapshotable/version.rb
CHANGED
data/lib/snapshotable.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'services/snapshot_creator'
|
2
4
|
|
3
5
|
module Snapshotable
|
6
|
+
# rubocop:disable Metrics/AbcSize
|
7
|
+
# rubocop:disable Metrics/MethodLength
|
8
|
+
# rubocop:disable Metrics/BlockLength
|
4
9
|
def self.included(base)
|
5
10
|
base.class_eval do
|
6
11
|
extend ClassMethods
|
@@ -41,6 +46,9 @@ module Snapshotable
|
|
41
46
|
end
|
42
47
|
end
|
43
48
|
end
|
49
|
+
# rubocop:enable Metrics/AbcSize
|
50
|
+
# rubocop:enable Metrics/MethodLength
|
51
|
+
# rubocop:enable Metrics/BlockLength
|
44
52
|
|
45
53
|
module ClassMethods
|
46
54
|
def snapshot(*attributes)
|
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.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- João Batista Marinho
|
@@ -12,7 +12,7 @@ cert_chain: []
|
|
12
12
|
date: 2018-08-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: activerecord
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '6'
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
|
-
name:
|
35
|
+
name: activesupport
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
@@ -133,6 +133,26 @@ dependencies:
|
|
133
133
|
- - "~>"
|
134
134
|
- !ruby/object:Gem::Version
|
135
135
|
version: '3.0'
|
136
|
+
- !ruby/object:Gem::Dependency
|
137
|
+
name: rubocop
|
138
|
+
requirement: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0.3'
|
143
|
+
- - "<"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '1'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.3'
|
153
|
+
- - "<"
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '1'
|
136
156
|
description: Caches a model in a time period
|
137
157
|
email: engineering@qulture.rocks
|
138
158
|
executables: []
|
@@ -160,7 +180,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
160
180
|
requirements:
|
161
181
|
- - ">="
|
162
182
|
- !ruby/object:Gem::Version
|
163
|
-
version: 2.
|
183
|
+
version: 2.3.0
|
164
184
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
185
|
requirements:
|
166
186
|
- - ">="
|