syncify 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +26 -1
- data/lib/syncify/sync.rb +8 -6
- data/lib/syncify/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7248fc338732c09e34209b7c01381195ae1f2af4
|
4
|
+
data.tar.gz: ab1f81a93c882e2055c47523c499de0a8f2620dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97cc971370901723a93e3241df248da0c57744403f9ef5582e8bb58b02da7e9b47fb450ba1e4c1bf208fa6c65284139707ba42e375feba00907875d7cf681c89
|
7
|
+
data.tar.gz: d87c63cbbda49f8f24312e19c68686e1327d3363df4eff2b4aabe30f4d0494df1a8ad9e9a7f4db2fd32bbc8b5400d76a507db5d354d211a6eccb918bcd9dd585
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
syncify (0.1.
|
4
|
+
syncify (0.1.2)
|
5
5
|
active_interaction (~> 3.0)
|
6
6
|
activerecord (~> 4.2)
|
7
7
|
activerecord-import (~> 0.17)
|
@@ -59,7 +59,7 @@ GEM
|
|
59
59
|
method_source (0.9.2)
|
60
60
|
mini_portile2 (2.4.0)
|
61
61
|
minitest (5.11.3)
|
62
|
-
nokogiri (1.10.
|
62
|
+
nokogiri (1.10.4)
|
63
63
|
mini_portile2 (~> 2.4.0)
|
64
64
|
pry (0.12.2)
|
65
65
|
coderay (~> 1.1.0)
|
@@ -76,7 +76,7 @@ GEM
|
|
76
76
|
activesupport (>= 4.2.0, < 5.0)
|
77
77
|
nokogiri (~> 1.6)
|
78
78
|
rails-deprecated_sanitizer (>= 1.0.1)
|
79
|
-
rails-html-sanitizer (1.
|
79
|
+
rails-html-sanitizer (1.2.0)
|
80
80
|
loofah (~> 2.2, >= 2.2.2)
|
81
81
|
railties (4.2.11.1)
|
82
82
|
actionpack (= 4.2.11.1)
|
data/README.md
CHANGED
@@ -24,7 +24,6 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
-
|
28
27
|
Syncify doesn't require Rails, just ActiveRecord, but it's a reasonable foundation for the following examples.
|
29
28
|
|
30
29
|
Also, you can sync from any environment to whatever your current environment is. So, you could sync from your staging environment to your client test environment or from staging to development. Heck, you could go from staging to prod if you'd like.
|
@@ -181,6 +180,32 @@ Syncify::Sync.run!(klass: Customer,
|
|
181
180
|
|
182
181
|
This will sync a customer, all of their invoices, all of those invoice's line items. It goes on to sync all of the line item's products, whether digital or physical, as well as the digital product's category and the physical product's distributor.
|
183
182
|
|
183
|
+
### Callbacks
|
184
|
+
|
185
|
+
Sometimes production databases contain sensitive data that you really don't want to have end up in other environments. Or, maybe you want to disassociate production data from third party production APIs. Or maybe you want to download images before you actually create image records locally. Syncify handles this by providing a callback mechanism.
|
186
|
+
|
187
|
+
Syncify's workflow is basically this:
|
188
|
+
|
189
|
+
1. Using the specified class and its associations, Syncify identifies all of the records we need to sync to the local environment. Effectively, all of the records are loaded from the remote environment into a set in memory.
|
190
|
+
2. Syncify calls an optional `callback` proc you can pass into the `run!` method.
|
191
|
+
3. Syncify actually bulk inserts all of the identified records into the local database.
|
192
|
+
|
193
|
+
By providing a `callback` proc, you can take some sort of action after all of the remote data has been identified, but before you write it locally. This includes modifying the remote data (in memory, not actually in the remote database).
|
194
|
+
|
195
|
+
Here's an example that masks personally identifiable information for users:
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
Syncify::Sync.run!(klass: User,
|
199
|
+
id: 40,
|
200
|
+
remote_database: :production,
|
201
|
+
callback:
|
202
|
+
proc do |identified_records|
|
203
|
+
user = identified_records.find { |record| record.class == User }
|
204
|
+
user.first_name = "#{user.first_name.first}#{'*' * (user.first_name.size - 1)}"
|
205
|
+
user.last_name = "#{user.last_name.first}#{'*' * (user.last_name.size - 1)}"
|
206
|
+
end
|
207
|
+
```
|
208
|
+
|
184
209
|
## Development
|
185
210
|
|
186
211
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/syncify/sync.rb
CHANGED
@@ -12,28 +12,29 @@ module Syncify
|
|
12
12
|
attr_accessor :identified_records
|
13
13
|
|
14
14
|
def execute
|
15
|
+
puts 'Identifying records to sync...'
|
15
16
|
@identified_records = Set[]
|
16
17
|
|
17
18
|
remote do
|
18
19
|
identify_associated_records(klass.find(id), normalized_associations(association))
|
19
20
|
end
|
20
21
|
|
22
|
+
puts "Identified #{identified_records.size} records to sync."
|
23
|
+
|
21
24
|
callback.call(identified_records) if callback.present?
|
22
25
|
|
23
26
|
sync_records
|
24
27
|
end
|
25
28
|
|
26
29
|
def identify_associated_records(root, associations)
|
30
|
+
print '.'
|
27
31
|
identified_records << root
|
28
32
|
|
29
33
|
standard_associations = associations.reject(&method(:includes_polymorphic_association))
|
30
34
|
polymorphic_associations = associations.select(&method(:includes_polymorphic_association))
|
31
35
|
|
32
36
|
standard_associations.each do |association|
|
33
|
-
traverse_associations(
|
34
|
-
root.class.eager_load(association).find(root.id),
|
35
|
-
association
|
36
|
-
)
|
37
|
+
traverse_associations(root.class.eager_load(association).find(root.id), association)
|
37
38
|
end
|
38
39
|
|
39
40
|
identify_polymorphic_associated_records(root, polymorphic_associations)
|
@@ -76,13 +77,14 @@ module Syncify
|
|
76
77
|
classify_identified_instances.each do |class_name, new_instances|
|
77
78
|
puts "Syncing #{new_instances.size} #{class_name} objects"
|
78
79
|
clazz = Object.const_get(class_name)
|
79
|
-
clazz.
|
80
|
+
clazz.where(id: [new_instances.map(&:id)]).delete_all
|
81
|
+
clazz.import(new_instances, validate: false)
|
80
82
|
end
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
84
86
|
def classify_identified_instances
|
85
|
-
puts "Classifying #{identified_records.size} records for bulk import
|
87
|
+
puts "Classifying #{identified_records.size} records for bulk import..."
|
86
88
|
|
87
89
|
identified_records.each_with_object({}) do |instance, memo|
|
88
90
|
clazz = instance.class
|
data/lib/syncify/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: syncify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Doug Hughes
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|