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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 732f3fd3c050a56656ad4eb272412d59528dd0ef
4
- data.tar.gz: 6e400731043ff844d4edb694ec68f7c354a68909
3
+ metadata.gz: 7248fc338732c09e34209b7c01381195ae1f2af4
4
+ data.tar.gz: ab1f81a93c882e2055c47523c499de0a8f2620dc
5
5
  SHA512:
6
- metadata.gz: d5c78f9f3b5306c79acbd67a37809166d6f296eb79dbff0183c7a6ecdeca3f0106602e1b003ebf67591208b476d727f2ccac40ae98f414568a5ccde73ba212cb
7
- data.tar.gz: 1c54d9823b93cb12d74d4b249222182f2b090c87c7cb83044b816aed3adc6c86fcaaf94f0d9601026f581e9a4a4b276e36928da1babaef7f52049d381824fd6d
6
+ metadata.gz: 97cc971370901723a93e3241df248da0c57744403f9ef5582e8bb58b02da7e9b47fb450ba1e4c1bf208fa6c65284139707ba42e375feba00907875d7cf681c89
7
+ data.tar.gz: d87c63cbbda49f8f24312e19c68686e1327d3363df4eff2b4aabe30f4d0494df1a8ad9e9a7f4db2fd32bbc8b5400d76a507db5d354d211a6eccb918bcd9dd585
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- syncify (0.1.0)
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.3)
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.1.0)
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.
@@ -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.import(new_instances, validate: false, on_duplicate_key_update: [:id])
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
@@ -1,3 +1,3 @@
1
1
  module Syncify
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
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.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-08 00:00:00.000000000 Z
11
+ date: 2019-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler