snapshotable 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|