remotable 0.4.0 → 0.5.0
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 +5 -5
- data/.gitignore +2 -0
- data/.travis.yml +21 -4
- data/Appraisals +24 -0
- data/README.mdown +64 -48
- data/gemfiles/rails_5.0.gemfile +8 -0
- data/gemfiles/rails_5.1.gemfile +8 -0
- data/gemfiles/rails_5.2.gemfile +8 -0
- data/gemfiles/rails_6.0.gemfile +8 -0
- data/gemfiles/rails_edge.gemfile +8 -0
- data/lib/remotable/active_record_extender.rb +50 -31
- data/lib/remotable/active_resource_fixes.rb +3 -13
- data/lib/remotable/nosync.rb +53 -21
- data/lib/remotable/validate_models.rb +8 -2
- data/lib/remotable/version.rb +1 -1
- data/remotable.gemspec +6 -5
- data/test/active_resource_test.rb +16 -17
- data/test/bespoke_test.rb +5 -7
- data/test/factories/tenants.rb +25 -20
- data/test/nosync_test.rb +1 -2
- data/test/null_remote_test.rb +3 -6
- data/test/test_helper.rb +15 -3
- data/test/understanding_test.rb +0 -2
- metadata +61 -15
- data/Gemfile.lock +0 -82
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: eb1390c1e1b04414cc0c44807a064f1d5d879c891a01988abcd7b919d9d53f37
|
4
|
+
data.tar.gz: 5f5b316b09904143182ba07de7225f1151328bc1dd12b52a3e5797b0b1f8dc03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef0d217377d44f7ea675da8ff0faf6718654502abec68cc2f388bc1d1ab95ecf7325aa20733608575d51842390510e9799326149b7ab31b075bcc8fe9902e188
|
7
|
+
data.tar.gz: 134e43c05eb6da221d66d1ae14bdb93f42d89c22a7b32336d505a81c3ad11e18f63ca5e52ca7838cebb52035221abbd9638473aa32c2bdef310c84bbd39e687c
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,11 +1,28 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.3
|
4
|
-
- 2.5
|
3
|
+
- 2.3
|
4
|
+
- 2.5
|
5
|
+
- 2.6
|
5
6
|
|
6
|
-
|
7
|
+
gemfile:
|
8
|
+
- gemfiles/rails_5.0.gemfile
|
9
|
+
- gemfiles/rails_5.1.gemfile
|
10
|
+
- gemfiles/rails_5.2.gemfile
|
11
|
+
- gemfiles/rails_6.0.gemfile
|
12
|
+
- gemfiles/rails_edge.gemfile
|
13
|
+
|
14
|
+
jobs:
|
15
|
+
exclude:
|
16
|
+
- rvm: 2.3
|
17
|
+
gemfile: gemfiles/rails_6.0.gemfile
|
18
|
+
- rvm: 2.3
|
19
|
+
gemfile: gemfiles/rails_edge.gemfile
|
20
|
+
- rvm: 2.4
|
21
|
+
gemfile: gemfiles/rails_6.0.gemfile
|
22
|
+
- rvm: 2.4
|
23
|
+
gemfile: gemfiles/rails_edge.gemfile
|
7
24
|
allow_failures:
|
8
|
-
|
25
|
+
- gemfile: gemfiles/rails_edge.gemfile
|
9
26
|
|
10
27
|
script: bundle exec rake test
|
11
28
|
|
data/Appraisals
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
appraise "rails-5.0" do
|
2
|
+
gem "activerecord", "~> 5.0.0"
|
3
|
+
gem "sqlite3", "~> 1.3.6"
|
4
|
+
end
|
5
|
+
|
6
|
+
appraise "rails-5.1" do
|
7
|
+
gem "activerecord", "~> 5.1.0"
|
8
|
+
gem "sqlite3", "~> 1.3.6"
|
9
|
+
end
|
10
|
+
|
11
|
+
appraise "rails-5.2" do
|
12
|
+
gem "activerecord", "~> 5.2.0"
|
13
|
+
gem "sqlite3", "~> 1.3.6"
|
14
|
+
end
|
15
|
+
|
16
|
+
appraise "rails-6.0" do
|
17
|
+
gem "activerecord", "~> 6.0.0"
|
18
|
+
gem "sqlite3", "~> 1.4.0"
|
19
|
+
end
|
20
|
+
|
21
|
+
appraise "rails-edge" do
|
22
|
+
gem "rails", git: "https://github.com/rails/rails.git", branch: "master", require: "activerecord"
|
23
|
+
gem "sqlite3", "~> 1.4.0"
|
24
|
+
end
|
data/README.mdown
CHANGED
@@ -20,29 +20,34 @@ Just add the following to your Gemfile:
|
|
20
20
|
|
21
21
|
**1.** Remotable requires that your local model have an `expires_at` column.
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
```ruby
|
24
|
+
class AddExpiresAtToTenants < ActiveRecord::Migration
|
25
|
+
def self.up
|
26
|
+
add_column :tenants, :expires_at, :timestamp, :null => false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
```
|
28
30
|
|
29
31
|
**2.** Your local model has to be associated with a remote model: (Let's say `RemoteTenant` is the name of an ActiveResource model.)
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
```ruby
|
34
|
+
class Tenant < ActiveRecord::Base
|
35
|
+
remote_model RemoteTenant
|
36
|
+
end
|
37
|
+
```
|
35
38
|
|
36
39
|
### Configuration
|
37
40
|
|
38
41
|
Specify the attributes of the local model that you want to keep in sync with the remote model. You can also specify mappings by using the hash rocket. The line `:customer_name => :name` tells Remotable to keep `RemoteTenant#customer_name` in sync with `Tenant#name`.
|
39
42
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
```ruby
|
44
|
+
class Tenant < ActiveRecord::Base
|
45
|
+
remote_model RemoteTenant
|
46
|
+
attr_remote :slug,
|
47
|
+
:customer_name => :name,
|
48
|
+
:id => :remote_id
|
49
|
+
end
|
50
|
+
```
|
46
51
|
|
47
52
|
### Remote Keys
|
48
53
|
|
@@ -50,24 +55,28 @@ By default Remotable assumes that the local model and remote model are joined wi
|
|
50
55
|
|
51
56
|
If you specify `attr_remote :id => :remote_id`, then the join will be on `local_model.remote_id=remote_model.id`, but you can also use a different attribute as the join key:
|
52
57
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
58
|
+
```ruby
|
59
|
+
class Tenant < ActiveRecord::Base
|
60
|
+
remote_model RemoteTenant
|
61
|
+
attr_remote :slug,
|
62
|
+
:customer_name => :name,
|
63
|
+
:id => :remote_id
|
64
|
+
remote_key :slug
|
65
|
+
end
|
66
|
+
```
|
60
67
|
|
61
68
|
Now, the join could be expressed this way: `local_model.slug=remote_model.slug`.
|
62
69
|
|
63
70
|
If you must look up a remote model with more than one attribute, you can express a composite key this way:
|
64
71
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
72
|
+
```ruby
|
73
|
+
class Event < ActiveRecord::Base
|
74
|
+
remote_model RemoteEvent
|
75
|
+
attr_remote :calendar_id,
|
76
|
+
:id => :remote_id
|
77
|
+
remote_key [:calendar_id, :remote_id]
|
78
|
+
end
|
79
|
+
```
|
71
80
|
|
72
81
|
### Finders
|
73
82
|
|
@@ -75,33 +84,38 @@ For `:id` or whatever you chose to be the remote key, Remotable will create a fi
|
|
75
84
|
|
76
85
|
You can create additional finder with the `fetch_with` method:
|
77
86
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
87
|
+
```ruby
|
88
|
+
class Tenant < ActiveRecord::Base
|
89
|
+
remote_model RemoteTenant
|
90
|
+
attr_remote :slug,
|
91
|
+
:customer_name => :name,
|
92
|
+
:id => :remote_id
|
93
|
+
fetch_with :slug
|
94
|
+
fetch_with :name
|
95
|
+
end
|
96
|
+
```
|
86
97
|
|
87
98
|
Remotable will create the following methods and assume the URI for the custom finders from the attribute. The example above will create the following methods:
|
88
99
|
|
100
|
+
```ruby
|
89
101
|
find_by_remote_id(...) # Looks in api_path/tenants/:id
|
90
102
|
find_by_slug(...) # Looks in api_path/tenants/by_slug/:slug
|
91
103
|
find_by_name(...) # Looks in api_path/tenants/by_name/:name
|
104
|
+
```
|
92
105
|
|
93
106
|
Note that the finder methods are named with the _local_ attributes.
|
94
107
|
|
95
108
|
You can specify a custom path with the `fetch_with` method:
|
96
109
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
110
|
+
```ruby
|
111
|
+
class Tenant < ActiveRecord::Base
|
112
|
+
remote_model RemoteTenant
|
113
|
+
attr_remote :slug,
|
114
|
+
:customer_name => :name,
|
115
|
+
:id => :remote_id
|
116
|
+
fetch_with :name, :path => "by_nombre/:name"
|
117
|
+
end
|
118
|
+
```
|
105
119
|
|
106
120
|
When you use `fetch_with`, give the name of the _local_ attribute not the remote one (if they differ). Also, the name of the symbolic part of the path should match the local attribute name as well.
|
107
121
|
|
@@ -109,10 +123,12 @@ When you use `fetch_with`, give the name of the _local_ attribute not the remote
|
|
109
123
|
|
110
124
|
Whenever a remoted record is instantiated, Remotable checks the value of its `expires_at` attribute. If the date is in the past, Remotable pulls changes from the remote resource. Whenever a record is saved, `expires_at` is set to a time in the future—by default, 1 day. You can change how frequently a record expires by setting `expires_after` to a duration:
|
111
125
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
126
|
+
```ruby
|
127
|
+
class Tenant < ActiveRecord::Base
|
128
|
+
remote_model RemoteTenant
|
129
|
+
expires_after 1.hour
|
130
|
+
end
|
131
|
+
```
|
116
132
|
|
117
133
|
### Adapters
|
118
134
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "remotable/core_ext"
|
2
2
|
require "active_support/concern"
|
3
3
|
require "active_support/core_ext/array/wrap"
|
4
|
+
require "active_resource/threadsafe_attributes"
|
4
5
|
require "benchmark"
|
5
6
|
|
6
7
|
|
@@ -25,10 +26,10 @@ module Remotable
|
|
25
26
|
|
26
27
|
validates_presence_of :expires_at
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
self._remote_attribute_map ||= default_remote_attributes.map_to_self
|
30
|
+
self._local_attribute_routes ||= {}
|
31
|
+
self._expires_after ||= 1.day
|
32
|
+
self._remote_timeout = {
|
32
33
|
:list => 4, # when we're getting many remote resources
|
33
34
|
:fetch => 4, # when we're getting a remote resource that doesn't exist locally
|
34
35
|
:pull => 1, # when we're getting a remote resource to refresh a local one
|
@@ -42,6 +43,10 @@ module Remotable
|
|
42
43
|
|
43
44
|
module ClassMethods
|
44
45
|
include Nosync
|
46
|
+
include ThreadsafeAttributes
|
47
|
+
|
48
|
+
threadsafe_attribute :_remote_key, :_expires_after, :_remote_attribute_map,
|
49
|
+
:_local_attribute_routes, :_remote_timeout, :remotable_skip_validation_on_sync
|
45
50
|
|
46
51
|
def nosync?
|
47
52
|
return true if remote_model.nil?
|
@@ -78,37 +83,43 @@ module Remotable
|
|
78
83
|
# Set up a finder method for the remote_key
|
79
84
|
fetch_with(local_key(remote_key), options)
|
80
85
|
|
81
|
-
|
86
|
+
self._remote_key = remote_key
|
82
87
|
else
|
83
|
-
|
88
|
+
_remote_key || generate_default_remote_key
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
87
92
|
def expires_after(*args)
|
88
|
-
|
89
|
-
|
93
|
+
self._expires_after = args.first if args.any?
|
94
|
+
_expires_after
|
90
95
|
end
|
91
96
|
|
92
97
|
def attr_remote(*attrs)
|
93
98
|
map = attrs.extract_options!
|
94
99
|
map = attrs.map_to_self.merge(map)
|
95
|
-
|
96
|
-
|
100
|
+
self._remote_attribute_map = map
|
101
|
+
self._local_attribute_routes = {} # reset routes
|
97
102
|
end
|
98
103
|
|
99
104
|
def remote_timeout(*args)
|
100
105
|
if args.any?
|
101
|
-
|
102
|
-
|
106
|
+
self._remote_timeout = n = args.first
|
107
|
+
self._remote_timeout = {:list => n, :fetch => n, :pull => n, :create => n, :update => n, :destroy => n} if n.is_a?(Numeric)
|
103
108
|
end
|
104
|
-
|
109
|
+
_remote_timeout
|
105
110
|
end
|
106
111
|
|
107
|
-
def
|
108
|
-
|
112
|
+
def remote_attribute_map
|
113
|
+
self._remote_attribute_map
|
109
114
|
end
|
110
115
|
|
111
|
-
|
116
|
+
def local_attribute_routes
|
117
|
+
self._local_attribute_routes
|
118
|
+
end
|
119
|
+
|
120
|
+
def fetch_with(local_key, options={})
|
121
|
+
self._local_attribute_routes.merge!(local_key => options[:path])
|
122
|
+
end
|
112
123
|
|
113
124
|
def remotable_skip_validation!
|
114
125
|
self.remotable_skip_validation_on_sync = true
|
@@ -119,10 +130,6 @@ module Remotable
|
|
119
130
|
end
|
120
131
|
|
121
132
|
|
122
|
-
|
123
|
-
attr_reader :remote_attribute_map,
|
124
|
-
:local_attribute_routes
|
125
|
-
|
126
133
|
def local_key(remote_key=nil)
|
127
134
|
remote_key ||= self.remote_key
|
128
135
|
if remote_key.is_a?(Array)
|
@@ -133,24 +140,24 @@ module Remotable
|
|
133
140
|
end
|
134
141
|
|
135
142
|
def remote_attribute_names
|
136
|
-
|
143
|
+
_remote_attribute_map.keys
|
137
144
|
end
|
138
145
|
|
139
146
|
def local_attribute_names
|
140
|
-
|
147
|
+
_remote_attribute_map.values
|
141
148
|
end
|
142
149
|
|
143
150
|
def remote_attribute_name(local_attr)
|
144
|
-
|
151
|
+
_remote_attribute_map.key(local_attr) || local_attr
|
145
152
|
end
|
146
153
|
|
147
154
|
def local_attribute_name(remote_attr)
|
148
|
-
|
155
|
+
_remote_attribute_map[remote_attr] || remote_attr
|
149
156
|
end
|
150
157
|
|
151
158
|
def route_for(remote_key)
|
152
159
|
local_key = self.local_key(remote_key)
|
153
|
-
|
160
|
+
_local_attribute_routes[local_key] || default_route_for(local_key, remote_key)
|
154
161
|
end
|
155
162
|
|
156
163
|
def default_route_for(local_key, remote_key=nil)
|
@@ -167,10 +174,23 @@ module Remotable
|
|
167
174
|
# !nb: this method is called when associations are loaded
|
168
175
|
# so you can use the remoted record in associations.
|
169
176
|
def instantiate(*args)
|
170
|
-
|
177
|
+
super.tap do |record|
|
178
|
+
sync_on_instantiate(record) unless ActiveRecord.version.segments.first > 5
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# !nb: In Rails 6+, this has been extracted from instantiate and can be called
|
183
|
+
# to instantiate homogenous sets of records without calling instantiate
|
184
|
+
def instantiate_instance_of(*args)
|
185
|
+
super.tap do |record|
|
186
|
+
sync_on_instantiate(record)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def sync_on_instantiate(record)
|
171
191
|
if record.expired? && !record.nosync?
|
172
192
|
begin
|
173
|
-
Remotable.logger.debug "[remotable:#{name.underscore}:
|
193
|
+
Remotable.logger.debug "[remotable:#{name.underscore}:sync_on_instantiate](#{record.fetch_value.inspect}) expired #{record.expires_at}"
|
174
194
|
record.pull_remote_data!
|
175
195
|
rescue Remotable::TimeoutError
|
176
196
|
report_ignored_timeout_error($!)
|
@@ -182,7 +202,6 @@ module Remotable
|
|
182
202
|
report_ignored_ssl_error($!)
|
183
203
|
end
|
184
204
|
end
|
185
|
-
record
|
186
205
|
end
|
187
206
|
|
188
207
|
def report_ignored_timeout_error(error)
|
@@ -254,7 +273,7 @@ module Remotable
|
|
254
273
|
generate_default_remote_key # <- Make sure we've figured out the remote
|
255
274
|
# primary key if we're evaluating a finder
|
256
275
|
|
257
|
-
return false unless
|
276
|
+
return false unless _local_attribute_routes.key?(local_key)
|
258
277
|
|
259
278
|
{ :local_attributes => local_attributes,
|
260
279
|
:remote_key => remote_key }
|
@@ -412,7 +431,7 @@ module Remotable
|
|
412
431
|
|
413
432
|
|
414
433
|
def generate_default_remote_key
|
415
|
-
return
|
434
|
+
return _remote_key if _remote_key
|
416
435
|
raise("No remote key supplied and :id is not a remote attribute") unless remote_attribute_names.member?(:id)
|
417
436
|
remote_key(:id)
|
418
437
|
end
|
@@ -554,7 +573,7 @@ module Remotable
|
|
554
573
|
true
|
555
574
|
else
|
556
575
|
merge_remote_errors(remote_resource.errors)
|
557
|
-
false
|
576
|
+
ActiveRecord.version.segments.first > 4 ? throw(:abort) : false
|
558
577
|
end
|
559
578
|
rescue Remotable::NotFound
|
560
579
|
report_ignored_404_on_destroy $!
|
@@ -1,10 +1,6 @@
|
|
1
1
|
require "active_resource"
|
2
|
-
require "active_support/concern"
|
3
|
-
|
4
2
|
|
5
3
|
module ActiveResourceFixes
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
4
|
|
9
5
|
# ! ActiveModel::AttributeMethods assumes that :attribute is the target
|
10
6
|
# for attribute lookup. ActiveResource doesn't define that method.
|
@@ -12,17 +8,11 @@ module ActiveResourceFixes
|
|
12
8
|
attributes[method]
|
13
9
|
end
|
14
10
|
|
15
|
-
|
16
|
-
included do
|
17
|
-
alias_method_chain :destroy, :validation
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
11
|
# ActiveResource::Validations overrides ActiveResource::Base#save
|
22
12
|
# to rescue from ActiveResource::ResourceInvalid and record the
|
23
13
|
# resource's errors. Do the same for `destroy`.
|
24
|
-
def
|
25
|
-
|
14
|
+
def destroy
|
15
|
+
super
|
26
16
|
rescue ActiveResource::ResourceInvalid => error
|
27
17
|
# cache the remote errors because every call to <tt>valid?</tt> clears
|
28
18
|
# all errors. We must keep a copy to add these back after local
|
@@ -34,7 +24,7 @@ module ActiveResourceFixes
|
|
34
24
|
|
35
25
|
end
|
36
26
|
|
37
|
-
ActiveResource::Base.send(:
|
27
|
+
ActiveResource::Base.send(:prepend, ActiveResourceFixes)
|
38
28
|
|
39
29
|
|
40
30
|
|
data/lib/remotable/nosync.rb
CHANGED
@@ -1,37 +1,69 @@
|
|
1
|
+
require "active_resource/threadsafe_attributes"
|
2
|
+
|
1
3
|
module Remotable
|
2
4
|
module Nosync
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
self.nosync = true
|
6
|
+
def self.included(base)
|
7
|
+
base.include InstanceMethods
|
7
8
|
end
|
8
9
|
|
9
|
-
def
|
10
|
-
|
11
|
-
self.nosync = new_value
|
12
|
-
yield
|
13
|
-
ensure
|
14
|
-
@nosync = old_value
|
10
|
+
def self.extended(base)
|
11
|
+
base.extend ClassMethods
|
15
12
|
end
|
16
13
|
|
17
|
-
|
18
|
-
@nosync = val
|
19
|
-
end
|
14
|
+
module InstanceMethods
|
20
15
|
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
def nosync!
|
17
|
+
self.nosync = true
|
18
|
+
end
|
24
19
|
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
def reset_nosync!
|
21
|
+
remove_instance_variable(:@nosync) if instance_variable_defined?(:@nosync)
|
22
|
+
end
|
23
|
+
|
24
|
+
def nosync(new_value=true)
|
25
|
+
old_value = _nosync
|
26
|
+
self.nosync = new_value
|
27
|
+
yield
|
28
|
+
ensure
|
29
|
+
self.nosync = old_value
|
30
|
+
end
|
31
|
+
|
32
|
+
def nosync=(val)
|
33
|
+
@nosync = val
|
34
|
+
end
|
28
35
|
|
29
|
-
|
36
|
+
def nosync_value?
|
37
|
+
!_nosync.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
def nosync?
|
41
|
+
!!_nosync
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def _nosync
|
47
|
+
@nosync if instance_variable_defined?(:@nosync)
|
48
|
+
end
|
30
49
|
|
31
|
-
def _nosync
|
32
|
-
@nosync if instance_variable_defined?(:@nosync)
|
33
50
|
end
|
34
51
|
|
52
|
+
module ClassMethods
|
53
|
+
include ThreadsafeAttributes
|
54
|
+
include InstanceMethods
|
55
|
+
|
56
|
+
def reset_nosync!
|
57
|
+
self.nosync = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def nosync=(val)
|
61
|
+
self._nosync = val
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
threadsafe_attribute :_nosync
|
66
|
+
end
|
35
67
|
|
36
68
|
end
|
37
69
|
end
|
@@ -1,13 +1,19 @@
|
|
1
|
+
require "active_resource/threadsafe_attributes"
|
2
|
+
|
1
3
|
module Remotable
|
2
4
|
module ValidateModels
|
5
|
+
include ThreadsafeAttributes
|
3
6
|
|
7
|
+
def self.extended(*args)
|
8
|
+
threadsafe_attribute :_validate_models
|
9
|
+
end
|
4
10
|
|
5
11
|
def validate_models=(val)
|
6
|
-
|
12
|
+
self._validate_models = (val == true)
|
7
13
|
end
|
8
14
|
|
9
15
|
def validate_models?
|
10
|
-
|
16
|
+
_validate_models == true
|
11
17
|
end
|
12
18
|
|
13
19
|
def without_validation
|
data/lib/remotable/version.rb
CHANGED
data/remotable.gemspec
CHANGED
@@ -11,17 +11,18 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.summary = %q{Binds an ActiveRecord model to a remote resource and keeps the two synchronized}
|
12
12
|
s.description = %q{Remotable keeps a locally-stored ActiveRecord synchronized with a remote resource.}
|
13
13
|
|
14
|
-
s.rubyforge_project = "remotable"
|
15
|
-
|
16
14
|
s.add_dependency "activeresource", ">= 3.2"
|
17
15
|
s.add_dependency "activerecord"
|
18
16
|
s.add_dependency "activesupport"
|
19
17
|
|
18
|
+
s.add_development_dependency "appraisal"
|
20
19
|
s.add_development_dependency "rake"
|
21
|
-
s.add_development_dependency "
|
20
|
+
s.add_development_dependency "minitest", "~> 5.10.3"
|
21
|
+
s.add_development_dependency "minitest-reporters"
|
22
|
+
s.add_development_dependency "minitest-reporters-turn_reporter"
|
22
23
|
s.add_development_dependency "pry"
|
23
|
-
s.add_development_dependency "
|
24
|
-
s.add_development_dependency "sqlite3"
|
24
|
+
s.add_development_dependency "factory_bot"
|
25
|
+
s.add_development_dependency "sqlite3"
|
25
26
|
s.add_development_dependency "active_resource_simulator"
|
26
27
|
s.add_development_dependency "simplecov"
|
27
28
|
s.add_development_dependency "rr"
|
@@ -7,7 +7,6 @@ require "rr"
|
|
7
7
|
|
8
8
|
|
9
9
|
class ActiveResourceTest < ActiveSupport::TestCase
|
10
|
-
include RR::Adapters::TestUnit
|
11
10
|
|
12
11
|
test "should make an absolute path and add the format" do
|
13
12
|
assert_equal "/api/accounts/by_slug/value.json", RemoteTenant.expanded_path_for("by_slug/value")
|
@@ -154,7 +153,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
154
153
|
# ========================================================================= #
|
155
154
|
|
156
155
|
test "should not fetch a remote record when a local record is not expired" do
|
157
|
-
tenant =
|
156
|
+
tenant = create(:tenant, :expires_at => 100.years.from_now)
|
158
157
|
unexpected_name = "Totally Wonky"
|
159
158
|
|
160
159
|
RemoteTenant.run_simulation do |s|
|
@@ -170,7 +169,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
170
169
|
end
|
171
170
|
|
172
171
|
test "should fetch a remote record when a local record is expired" do
|
173
|
-
tenant =
|
172
|
+
tenant = create(:tenant, :expires_at => 1.year.ago)
|
174
173
|
unexpected_name = "Totally Wonky"
|
175
174
|
|
176
175
|
RemoteTenant.run_simulation do |s|
|
@@ -186,7 +185,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
186
185
|
end
|
187
186
|
|
188
187
|
test "should treat a 304 response as no changes" do
|
189
|
-
tenant =
|
188
|
+
tenant = create(:tenant, :expires_at => 1.year.ago)
|
190
189
|
|
191
190
|
RemoteTenant.run_simulation do |s|
|
192
191
|
s.show(tenant.remote_id, nil, :status => 304, :headers => if_modified_since(tenant))
|
@@ -199,7 +198,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
199
198
|
|
200
199
|
test "should ignore a 503 response" do
|
201
200
|
expired_at = 1.year.ago
|
202
|
-
tenant =
|
201
|
+
tenant = create(:tenant, :expires_at => expired_at)
|
203
202
|
|
204
203
|
RemoteTenant.run_simulation do |s|
|
205
204
|
s.show(tenant.remote_id, nil, :status => 503, :headers => if_modified_since(tenant))
|
@@ -219,7 +218,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
219
218
|
# ========================================================================= #
|
220
219
|
|
221
220
|
test "should update a record remotely when updating one locally" do
|
222
|
-
tenant =
|
221
|
+
tenant = create(:tenant)
|
223
222
|
new_name = "Totally Wonky"
|
224
223
|
|
225
224
|
RemoteTenant.run_simulation do |s|
|
@@ -242,7 +241,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
242
241
|
end
|
243
242
|
|
244
243
|
test "should be able to update resources by different attributes" do
|
245
|
-
tenant = RemoteWithKey.where(id:
|
244
|
+
tenant = RemoteWithKey.where(id: create(:tenant).id).first
|
246
245
|
new_name = "Totally Wonky"
|
247
246
|
|
248
247
|
RemoteTenant.run_simulation do |s|
|
@@ -265,7 +264,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
265
264
|
end
|
266
265
|
|
267
266
|
test "should fail to update a record locally when failing to update one remotely" do
|
268
|
-
tenant =
|
267
|
+
tenant = create(:tenant)
|
269
268
|
new_name = "Totally Wonky"
|
270
269
|
|
271
270
|
RemoteTenant.run_simulation do |s|
|
@@ -363,7 +362,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
363
362
|
# ========================================================================= #
|
364
363
|
|
365
364
|
test "should destroy a record remotely when destroying one locally" do
|
366
|
-
tenant =
|
365
|
+
tenant = create(:tenant)
|
367
366
|
|
368
367
|
RemoteTenant.run_simulation do |s|
|
369
368
|
s.show(tenant.remote_id, {
|
@@ -381,7 +380,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
381
380
|
end
|
382
381
|
|
383
382
|
test "should destroy resources by different attributes" do
|
384
|
-
tenant = RemoteWithKey.where(id:
|
383
|
+
tenant = RemoteWithKey.where(id: create(:tenant).id).first
|
385
384
|
new_name = "Totally Wonky"
|
386
385
|
|
387
386
|
RemoteTenant.run_simulation do |s|
|
@@ -399,7 +398,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
399
398
|
end
|
400
399
|
|
401
400
|
test "should fail to destroy a record locally when failing to destroy one remotely" do
|
402
|
-
tenant =
|
401
|
+
tenant = create(:tenant)
|
403
402
|
|
404
403
|
RemoteTenant.run_simulation do |s|
|
405
404
|
s.show(tenant.remote_id, {
|
@@ -420,7 +419,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
420
419
|
end
|
421
420
|
|
422
421
|
test "should succeed in destroying a record locally when the remote source is not found" do
|
423
|
-
tenant =
|
422
|
+
tenant = create(:tenant)
|
424
423
|
|
425
424
|
RemoteTenant.run_simulation do |s|
|
426
425
|
s.show(tenant.remote_id, {
|
@@ -439,7 +438,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
439
438
|
end
|
440
439
|
|
441
440
|
test "should delete a local record when a remote record has been deleted" do
|
442
|
-
tenant =
|
441
|
+
tenant = create(:tenant, :expires_at => 1.year.ago)
|
443
442
|
|
444
443
|
assert_difference "Tenant.count", -1 do
|
445
444
|
RemoteTenant.run_simulation do |s|
|
@@ -459,7 +458,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
459
458
|
# ========================================================================= #
|
460
459
|
|
461
460
|
test "should be able to find all remote resources and sync them with local resources" do
|
462
|
-
tenant =
|
461
|
+
tenant = create(:tenant, :expires_at => 1.year.ago)
|
463
462
|
|
464
463
|
assert_equal 1, Tenant.count, "There's supposed to be 1 tenant"
|
465
464
|
|
@@ -467,10 +466,10 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
467
466
|
assert_difference "Tenant.count", +1 do
|
468
467
|
RemoteTenant.run_simulation do |s|
|
469
468
|
s.show(nil, [
|
470
|
-
{ :id => tenant.
|
469
|
+
{ :id => tenant.remote_id,
|
471
470
|
:slug => "a-different-slug",
|
472
471
|
:church_name => "A Different Name" },
|
473
|
-
{ :id => tenant.
|
472
|
+
{ :id => tenant.remote_id + 1,
|
474
473
|
:slug => "generic-slug",
|
475
474
|
:church_name => "Generic Name" }],
|
476
475
|
:path => "/api/accounts.json")
|
@@ -501,7 +500,7 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
501
500
|
end
|
502
501
|
|
503
502
|
test "should ignore a Remotable::TimeoutError when instantiating a record" do
|
504
|
-
tenant =
|
503
|
+
tenant = create(:tenant, :expires_at => 1.year.ago)
|
505
504
|
|
506
505
|
assert_nothing_raised do
|
507
506
|
stub(Tenant.remote_model).find do |*args|
|
data/test/bespoke_test.rb
CHANGED
@@ -5,8 +5,6 @@ require "rr"
|
|
5
5
|
|
6
6
|
|
7
7
|
class BespokeTest < ActiveSupport::TestCase
|
8
|
-
include RR::Adapters::TestUnit
|
9
|
-
|
10
8
|
|
11
9
|
teardown do
|
12
10
|
def model.new_resource
|
@@ -68,7 +66,7 @@ class BespokeTest < ActiveSupport::TestCase
|
|
68
66
|
# ========================================================================= #
|
69
67
|
|
70
68
|
test "should update a record remotely when updating one locally" do
|
71
|
-
@tenant =
|
69
|
+
@tenant = create(:bespoke_tenant)
|
72
70
|
new_name = "Totally Wonky"
|
73
71
|
|
74
72
|
# RemoteTenant.run_simulation do |s|
|
@@ -90,7 +88,7 @@ class BespokeTest < ActiveSupport::TestCase
|
|
90
88
|
end
|
91
89
|
|
92
90
|
test "should fail to update a record locally when failing to update one remotely" do
|
93
|
-
@tenant =
|
91
|
+
@tenant = create(:bespoke_tenant, :nosync => false)
|
94
92
|
|
95
93
|
def model.find_by(attribute, value)
|
96
94
|
BespokeResource.new(attribute => value)
|
@@ -156,13 +154,13 @@ class BespokeTest < ActiveSupport::TestCase
|
|
156
154
|
# ========================================================================= #
|
157
155
|
|
158
156
|
test "should destroy a record remotely when destroying one locally" do
|
159
|
-
@tenant =
|
157
|
+
@tenant = create(:bespoke_tenant, :nosync => false)
|
160
158
|
mock(resource).destroy { true }
|
161
159
|
@tenant.destroy
|
162
160
|
end
|
163
161
|
|
164
162
|
test "should fail to destroy a record locally when failing to destroy one remotely" do
|
165
|
-
@tenant =
|
163
|
+
@tenant = create(:bespoke_tenant, :nosync => false)
|
166
164
|
mock(resource).destroy { raise StandardError }
|
167
165
|
assert_raises(StandardError) do
|
168
166
|
@tenant.destroy
|
@@ -170,7 +168,7 @@ class BespokeTest < ActiveSupport::TestCase
|
|
170
168
|
end
|
171
169
|
|
172
170
|
test "should delete a local record when a remote record has been deleted" do
|
173
|
-
@tenant =
|
171
|
+
@tenant = create(:bespoke_tenant, :expires_at => 1.year.ago)
|
174
172
|
|
175
173
|
def model.find_by(remote_attr, value)
|
176
174
|
nil
|
data/test/factories/tenants.rb
CHANGED
@@ -1,23 +1,28 @@
|
|
1
|
-
|
2
|
-
f.sequence(:slug) { |n| "test#{n}" }
|
3
|
-
f.name "Test"
|
4
|
-
f.sequence(:remote_id)
|
5
|
-
f.expires_at 100.years.from_now
|
6
|
-
f.nosync true
|
7
|
-
end
|
1
|
+
FactoryBot.define do
|
8
2
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
3
|
+
factory :tenant do
|
4
|
+
sequence(:slug) { |n| "test#{n}" }
|
5
|
+
name { "Test" }
|
6
|
+
sequence :remote_id
|
7
|
+
expires_at { 100.years.from_now }
|
8
|
+
nosync { true }
|
9
|
+
end
|
10
|
+
|
11
|
+
factory :bespoke_tenant do
|
12
|
+
sequence(:slug) { |n| "test#{n}" }
|
13
|
+
name { "Test" }
|
14
|
+
sequence :remote_id
|
15
|
+
expires_at { 100.years.from_now }
|
16
|
+
nosync { true }
|
17
|
+
end
|
18
|
+
|
19
|
+
factory :null_test_tenant do
|
20
|
+
sequence(:slug) { |n| "test#{n}" }
|
21
|
+
name { "Test" }
|
22
|
+
sequence :remote_id
|
23
|
+
expires_at { 100.years.from_now }
|
24
|
+
nosync { true }
|
25
|
+
end
|
16
26
|
|
17
|
-
Factory.define :null_test_tenant do |f|
|
18
|
-
f.sequence(:slug) { |n| "test#{n}" }
|
19
|
-
f.name "Test"
|
20
|
-
f.sequence(:remote_id)
|
21
|
-
f.expires_at 100.years.from_now
|
22
|
-
f.nosync true
|
23
27
|
end
|
28
|
+
|
data/test/nosync_test.rb
CHANGED
@@ -6,7 +6,6 @@ require "support/active_resource"
|
|
6
6
|
class NoSyncTest < ActiveSupport::TestCase
|
7
7
|
|
8
8
|
|
9
|
-
|
10
9
|
test "nosync? should be false by default" do
|
11
10
|
assert_equal false, Tenant.new.nosync?
|
12
11
|
end
|
@@ -56,7 +55,7 @@ class NoSyncTest < ActiveSupport::TestCase
|
|
56
55
|
# ========================================================================= #
|
57
56
|
|
58
57
|
test "should do nothing if a tenant is expired" do
|
59
|
-
tenant =
|
58
|
+
tenant = create(:tenant, :expires_at => 1.year.ago)
|
60
59
|
|
61
60
|
Remotable.nosync do
|
62
61
|
result = Tenant.find_by_remote_id(tenant.remote_id)
|
data/test/null_remote_test.rb
CHANGED
@@ -4,16 +4,13 @@ require "support/null"
|
|
4
4
|
|
5
5
|
|
6
6
|
class NullRemoteTest < ActiveSupport::TestCase
|
7
|
-
include RR::Adapters::TestUnit
|
8
|
-
|
9
|
-
|
10
7
|
|
11
8
|
# ========================================================================= #
|
12
9
|
# Finding #
|
13
10
|
# ========================================================================= #
|
14
11
|
|
15
12
|
test "should do nothing if a tenant is expired" do
|
16
|
-
tenant =
|
13
|
+
tenant = create(:null_test_tenant, expires_at: 2.days.ago)
|
17
14
|
result = NullTestTenant.find_by_slug(tenant.slug)
|
18
15
|
assert_equal tenant, result
|
19
16
|
end
|
@@ -35,7 +32,7 @@ class NullRemoteTest < ActiveSupport::TestCase
|
|
35
32
|
# ========================================================================= #
|
36
33
|
|
37
34
|
test "should update a record locally without any interference" do
|
38
|
-
tenant =
|
35
|
+
tenant = create(:null_test_tenant)
|
39
36
|
new_name = "Totally Wonky"
|
40
37
|
|
41
38
|
tenant.name = new_name
|
@@ -63,7 +60,7 @@ class NullRemoteTest < ActiveSupport::TestCase
|
|
63
60
|
# ========================================================================= #
|
64
61
|
|
65
62
|
test "should destroy a record locally without any interference" do
|
66
|
-
tenant =
|
63
|
+
tenant = create(:null_test_tenant)
|
67
64
|
tenant.nosync = false
|
68
65
|
tenant.destroy
|
69
66
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
require "rubygems"
|
2
|
-
require "
|
2
|
+
require "active_support"
|
3
3
|
require "active_support/core_ext"
|
4
|
-
require "
|
5
|
-
require "
|
4
|
+
require "simplecov"
|
5
|
+
require "factory_bot"
|
6
6
|
require "pry"
|
7
7
|
require "database_cleaner"
|
8
8
|
require "active_record"
|
9
9
|
require "factories/tenants"
|
10
10
|
require "minitest/autorun"
|
11
|
+
require "minitest/reporters/turn_reporter"
|
12
|
+
|
13
|
+
Minitest::Reporters.use! Minitest::Reporters::TurnReporter.new
|
11
14
|
|
12
15
|
ActiveRecord::Base.establish_connection(
|
13
16
|
:adapter => "sqlite3",
|
@@ -19,10 +22,19 @@ load File.join(File.dirname(__FILE__), "support", "schema.rb")
|
|
19
22
|
DatabaseCleaner.strategy = :transaction
|
20
23
|
|
21
24
|
class ActiveSupport::TestCase
|
25
|
+
include FactoryBot::Syntax::Methods
|
26
|
+
|
22
27
|
setup do
|
23
28
|
DatabaseCleaner.start
|
24
29
|
end
|
25
30
|
teardown do
|
26
31
|
DatabaseCleaner.clean
|
32
|
+
|
33
|
+
Remotable.reset_nosync!
|
34
|
+
Tenant.reset_nosync!
|
35
|
+
BespokeTenant.reset_nosync!
|
36
|
+
RemoteWithoutKey.reset_nosync!
|
37
|
+
RemoteWithKey.reset_nosync!
|
38
|
+
RemoteWithCompositeKey.reset_nosync!
|
27
39
|
end
|
28
40
|
end
|
data/test/understanding_test.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remotable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Lail
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activeresource
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: appraisal
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rake
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,7 +81,35 @@ dependencies:
|
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: minitest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 5.10.3
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 5.10.3
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: minitest-reporters
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: minitest-reporters-turn_reporter
|
71
113
|
requirement: !ruby/object:Gem::Requirement
|
72
114
|
requirements:
|
73
115
|
- - ">="
|
@@ -95,33 +137,33 @@ dependencies:
|
|
95
137
|
- !ruby/object:Gem::Version
|
96
138
|
version: '0'
|
97
139
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
140
|
+
name: factory_bot
|
99
141
|
requirement: !ruby/object:Gem::Requirement
|
100
142
|
requirements:
|
101
|
-
- - "
|
143
|
+
- - ">="
|
102
144
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
145
|
+
version: '0'
|
104
146
|
type: :development
|
105
147
|
prerelease: false
|
106
148
|
version_requirements: !ruby/object:Gem::Requirement
|
107
149
|
requirements:
|
108
|
-
- - "
|
150
|
+
- - ">="
|
109
151
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
152
|
+
version: '0'
|
111
153
|
- !ruby/object:Gem::Dependency
|
112
154
|
name: sqlite3
|
113
155
|
requirement: !ruby/object:Gem::Requirement
|
114
156
|
requirements:
|
115
|
-
- - "
|
157
|
+
- - ">="
|
116
158
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
159
|
+
version: '0'
|
118
160
|
type: :development
|
119
161
|
prerelease: false
|
120
162
|
version_requirements: !ruby/object:Gem::Requirement
|
121
163
|
requirements:
|
122
|
-
- - "
|
164
|
+
- - ">="
|
123
165
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
166
|
+
version: '0'
|
125
167
|
- !ruby/object:Gem::Dependency
|
126
168
|
name: active_resource_simulator
|
127
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -189,11 +231,16 @@ files:
|
|
189
231
|
- ".gitignore"
|
190
232
|
- ".simplecov"
|
191
233
|
- ".travis.yml"
|
234
|
+
- Appraisals
|
192
235
|
- Gemfile
|
193
|
-
- Gemfile.lock
|
194
236
|
- MIT-LICENSE
|
195
237
|
- README.mdown
|
196
238
|
- Rakefile
|
239
|
+
- gemfiles/rails_5.0.gemfile
|
240
|
+
- gemfiles/rails_5.1.gemfile
|
241
|
+
- gemfiles/rails_5.2.gemfile
|
242
|
+
- gemfiles/rails_6.0.gemfile
|
243
|
+
- gemfiles/rails_edge.gemfile
|
197
244
|
- lib/remotable.rb
|
198
245
|
- lib/remotable/active_record_extender.rb
|
199
246
|
- lib/remotable/active_resource_fixes.rb
|
@@ -242,8 +289,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
242
289
|
- !ruby/object:Gem::Version
|
243
290
|
version: '0'
|
244
291
|
requirements: []
|
245
|
-
|
246
|
-
rubygems_version: 2.6.11
|
292
|
+
rubygems_version: 3.0.3
|
247
293
|
signing_key:
|
248
294
|
specification_version: 4
|
249
295
|
summary: Binds an ActiveRecord model to a remote resource and keeps the two synchronized
|
data/Gemfile.lock
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
remotable (0.4.0)
|
5
|
-
activerecord
|
6
|
-
activeresource (>= 3.2)
|
7
|
-
activesupport
|
8
|
-
|
9
|
-
GEM
|
10
|
-
remote: http://rubygems.org/
|
11
|
-
specs:
|
12
|
-
active_resource_simulator (0.0.2)
|
13
|
-
activeresource
|
14
|
-
activemodel (4.0.13)
|
15
|
-
activesupport (= 4.0.13)
|
16
|
-
builder (~> 3.1.0)
|
17
|
-
activerecord (4.0.13)
|
18
|
-
activemodel (= 4.0.13)
|
19
|
-
activerecord-deprecated_finders (~> 1.0.2)
|
20
|
-
activesupport (= 4.0.13)
|
21
|
-
arel (~> 4.0.0)
|
22
|
-
activerecord-deprecated_finders (1.0.4)
|
23
|
-
activeresource (4.1.0)
|
24
|
-
activemodel (~> 4.0)
|
25
|
-
activesupport (~> 4.0)
|
26
|
-
rails-observers (~> 0.1.2)
|
27
|
-
activesupport (4.0.13)
|
28
|
-
i18n (~> 0.6, >= 0.6.9)
|
29
|
-
minitest (~> 4.2)
|
30
|
-
multi_json (~> 1.3)
|
31
|
-
thread_safe (~> 0.1)
|
32
|
-
tzinfo (~> 0.3.37)
|
33
|
-
ansi (1.5.0)
|
34
|
-
arel (4.0.2)
|
35
|
-
builder (3.1.4)
|
36
|
-
coderay (1.1.2)
|
37
|
-
concurrent-ruby (1.0.5)
|
38
|
-
database_cleaner (1.2.0)
|
39
|
-
docile (1.3.1)
|
40
|
-
factory_girl (2.0.5)
|
41
|
-
i18n (0.9.5)
|
42
|
-
concurrent-ruby (~> 1.0)
|
43
|
-
json (2.1.0)
|
44
|
-
method_source (0.9.0)
|
45
|
-
minitest (4.7.5)
|
46
|
-
multi_json (1.13.1)
|
47
|
-
pry (0.11.3)
|
48
|
-
coderay (~> 1.1.0)
|
49
|
-
method_source (~> 0.9.0)
|
50
|
-
rails-observers (0.1.5)
|
51
|
-
activemodel (>= 4.0)
|
52
|
-
rake (12.3.1)
|
53
|
-
rr (1.1.2)
|
54
|
-
simplecov (0.16.1)
|
55
|
-
docile (~> 1.1)
|
56
|
-
json (>= 1.8, < 3)
|
57
|
-
simplecov-html (~> 0.10.0)
|
58
|
-
simplecov-html (0.10.2)
|
59
|
-
sqlite3 (1.3.13)
|
60
|
-
thread_safe (0.3.6)
|
61
|
-
turn (0.9.7)
|
62
|
-
ansi
|
63
|
-
minitest (~> 4)
|
64
|
-
tzinfo (0.3.54)
|
65
|
-
|
66
|
-
PLATFORMS
|
67
|
-
ruby
|
68
|
-
|
69
|
-
DEPENDENCIES
|
70
|
-
active_resource_simulator
|
71
|
-
database_cleaner
|
72
|
-
factory_girl (~> 2.0.4)
|
73
|
-
pry
|
74
|
-
rake
|
75
|
-
remotable!
|
76
|
-
rr
|
77
|
-
simplecov
|
78
|
-
sqlite3 (~> 1.3.13)
|
79
|
-
turn
|
80
|
-
|
81
|
-
BUNDLED WITH
|
82
|
-
1.16.1
|