remotable 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +0 -1
- data/Gemfile.lock +125 -0
- data/lib/remotable/active_record_extender.rb +57 -24
- data/lib/remotable/null_remote.rb +51 -0
- data/lib/remotable/version.rb +1 -1
- data/lib/remotable.rb +4 -2
- data/remotable.gemspec +1 -0
- data/test/active_resource_test.rb +32 -0
- data/test/factories/tenants.rb +8 -0
- data/test/nosync_test.rb +15 -0
- data/test/null_remote_test.rb +73 -0
- data/test/remotable_test.rb +4 -5
- data/test/support/active_resource.rb +3 -3
- data/test/support/bespoke.rb +1 -1
- data/test/support/null.rb +10 -0
- data/test/test_helper.rb +1 -0
- metadata +51 -63
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e84548b3d422a45df52d3a730cbe4d41d78c954e
|
4
|
+
data.tar.gz: 4734d71d361ec0ca5f9634a660f53a1375ad5670
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1d89d1ffb5585fc6f9219460f901c61e9c3512260272daa87fa15d3c68a0c3bf914bbf921a23d6f62def17d04ff0186583bebff9a6d20cda3cc3bc0cc5a1d451
|
7
|
+
data.tar.gz: c4da1216f5058cc9d7b4a1b265601edc41f44769efdf05950fa2c8cc0f40020d2c1895aa7b306e6176095fa7679bff799c3e8b35060033cde1a3460f013d8ae5
|
data/.gitignore
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
remotable (0.2.4)
|
5
|
+
activerecord
|
6
|
+
activeresource
|
7
|
+
activesupport
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
actionmailer (3.2.13)
|
13
|
+
actionpack (= 3.2.13)
|
14
|
+
mail (~> 2.5.3)
|
15
|
+
actionpack (3.2.13)
|
16
|
+
activemodel (= 3.2.13)
|
17
|
+
activesupport (= 3.2.13)
|
18
|
+
builder (~> 3.0.0)
|
19
|
+
erubis (~> 2.7.0)
|
20
|
+
journey (~> 1.0.4)
|
21
|
+
rack (~> 1.4.5)
|
22
|
+
rack-cache (~> 1.2)
|
23
|
+
rack-test (~> 0.6.1)
|
24
|
+
sprockets (~> 2.2.1)
|
25
|
+
active_resource_simulator (0.0.1)
|
26
|
+
activeresource
|
27
|
+
activemodel (3.2.13)
|
28
|
+
activesupport (= 3.2.13)
|
29
|
+
builder (~> 3.0.0)
|
30
|
+
activerecord (3.2.13)
|
31
|
+
activemodel (= 3.2.13)
|
32
|
+
activesupport (= 3.2.13)
|
33
|
+
arel (~> 3.0.2)
|
34
|
+
tzinfo (~> 0.3.29)
|
35
|
+
activeresource (3.2.13)
|
36
|
+
activemodel (= 3.2.13)
|
37
|
+
activesupport (= 3.2.13)
|
38
|
+
activesupport (3.2.13)
|
39
|
+
i18n (= 0.6.1)
|
40
|
+
multi_json (~> 1.0)
|
41
|
+
ansi (1.4.3)
|
42
|
+
arel (3.0.2)
|
43
|
+
builder (3.0.4)
|
44
|
+
coderay (1.0.8)
|
45
|
+
database_cleaner (0.6.7)
|
46
|
+
erubis (2.7.0)
|
47
|
+
factory_girl (2.0.4)
|
48
|
+
hike (1.2.1)
|
49
|
+
i18n (0.6.1)
|
50
|
+
journey (1.0.4)
|
51
|
+
json (1.7.7)
|
52
|
+
mail (2.5.3)
|
53
|
+
i18n (>= 0.4.0)
|
54
|
+
mime-types (~> 1.16)
|
55
|
+
treetop (~> 1.4.8)
|
56
|
+
method_source (0.8.1)
|
57
|
+
mime-types (1.21)
|
58
|
+
minitest (2.10.0)
|
59
|
+
multi_json (1.0.3)
|
60
|
+
polyglot (0.3.3)
|
61
|
+
pry (0.9.10)
|
62
|
+
coderay (~> 1.0.5)
|
63
|
+
method_source (~> 0.8)
|
64
|
+
slop (~> 3.3.1)
|
65
|
+
rack (1.4.5)
|
66
|
+
rack-cache (1.2)
|
67
|
+
rack (>= 0.4)
|
68
|
+
rack-ssl (1.3.3)
|
69
|
+
rack
|
70
|
+
rack-test (0.6.2)
|
71
|
+
rack (>= 1.0)
|
72
|
+
rails (3.2.13)
|
73
|
+
actionmailer (= 3.2.13)
|
74
|
+
actionpack (= 3.2.13)
|
75
|
+
activerecord (= 3.2.13)
|
76
|
+
activeresource (= 3.2.13)
|
77
|
+
activesupport (= 3.2.13)
|
78
|
+
bundler (~> 1.0)
|
79
|
+
railties (= 3.2.13)
|
80
|
+
railties (3.2.13)
|
81
|
+
actionpack (= 3.2.13)
|
82
|
+
activesupport (= 3.2.13)
|
83
|
+
rack-ssl (~> 1.3.2)
|
84
|
+
rake (>= 0.8.7)
|
85
|
+
rdoc (~> 3.4)
|
86
|
+
thor (>= 0.14.6, < 2.0)
|
87
|
+
rake (10.0.3)
|
88
|
+
rdoc (3.12.2)
|
89
|
+
json (~> 1.4)
|
90
|
+
rr (1.0.4)
|
91
|
+
simplecov (0.5.3)
|
92
|
+
multi_json (~> 1.0.3)
|
93
|
+
simplecov-html (~> 0.5.3)
|
94
|
+
simplecov-html (0.5.3)
|
95
|
+
slop (3.3.3)
|
96
|
+
sprockets (2.2.2)
|
97
|
+
hike (~> 1.2)
|
98
|
+
multi_json (~> 1.0)
|
99
|
+
rack (~> 1.0)
|
100
|
+
tilt (~> 1.1, != 1.3.0)
|
101
|
+
sqlite3 (1.3.7)
|
102
|
+
thor (0.17.0)
|
103
|
+
tilt (1.3.6)
|
104
|
+
treetop (1.4.12)
|
105
|
+
polyglot
|
106
|
+
polyglot (>= 0.3.1)
|
107
|
+
turn (0.9.6)
|
108
|
+
ansi
|
109
|
+
tzinfo (0.3.37)
|
110
|
+
|
111
|
+
PLATFORMS
|
112
|
+
ruby
|
113
|
+
|
114
|
+
DEPENDENCIES
|
115
|
+
active_resource_simulator
|
116
|
+
database_cleaner
|
117
|
+
factory_girl
|
118
|
+
minitest
|
119
|
+
pry
|
120
|
+
rails
|
121
|
+
remotable!
|
122
|
+
rr
|
123
|
+
simplecov
|
124
|
+
sqlite3
|
125
|
+
turn
|
@@ -81,11 +81,7 @@ module Remotable
|
|
81
81
|
map = attrs.extract_options!
|
82
82
|
map = attrs.map_to_self.merge(map)
|
83
83
|
@remote_attribute_map = map
|
84
|
-
|
85
|
-
assert_that_remote_resource_responds_to_remote_attributes!(remote_model) if Remotable.validate_models?
|
86
|
-
|
87
|
-
# Reset routes
|
88
|
-
@local_attribute_routes = {}
|
84
|
+
@local_attribute_routes = {} # reset routes
|
89
85
|
end
|
90
86
|
|
91
87
|
def fetch_with(local_key, options={})
|
@@ -129,7 +125,6 @@ module Remotable
|
|
129
125
|
end
|
130
126
|
|
131
127
|
def default_route_for(local_key, remote_key=nil)
|
132
|
-
puts "local_key: #{local_key}; remote_key: #{remote_key}"
|
133
128
|
remote_key ||= remote_attribute_name(local_key)
|
134
129
|
if remote_key.to_s == primary_key
|
135
130
|
":#{local_key}"
|
@@ -260,30 +255,62 @@ module Remotable
|
|
260
255
|
|
261
256
|
|
262
257
|
|
263
|
-
|
258
|
+
def all_by_remote
|
259
|
+
find_by_remote_query(:all)
|
260
|
+
end
|
264
261
|
|
262
|
+
def find_by_remote_query(remote_method_name, *args)
|
263
|
+
remote_resources = remote_model.send(remote_method_name, *args)
|
264
|
+
map_remote_resources_to_local(remote_resources)
|
265
|
+
end
|
265
266
|
|
267
|
+
def map_remote_resources_to_local(remote_resources)
|
268
|
+
return [] if remote_resources.empty?
|
269
|
+
|
270
|
+
local_resources = nosync { fetch_corresponding_local_resources(remote_resources).to_a }
|
271
|
+
|
272
|
+
# Ensure a corresponding local resource for
|
273
|
+
# each remote resource; return the set of
|
274
|
+
# local resources.
|
275
|
+
remote_resources.map do |remote_resource|
|
276
|
+
|
277
|
+
# Get the specific local resource that
|
278
|
+
# corresponds to this remote one.
|
279
|
+
local_resource = local_resources.detect { |local_resource|
|
280
|
+
Array.wrap(remote_key).all? { |remote_attr|
|
281
|
+
local_attr = local_attribute_name(remote_attr)
|
282
|
+
local_resource.send(local_attr) == remote_resource.send(remote_attr)
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
286
|
+
# If a local counterpart to this remote value
|
287
|
+
# exists, update the local resource and return it.
|
288
|
+
# If not, create a local counterpart and return it.
|
289
|
+
if local_resource
|
290
|
+
local_resource.instance_variable_set :@remote_resource, remote_resource
|
291
|
+
local_resource.pull_remote_data!
|
292
|
+
else
|
293
|
+
new_from_remote(remote_resource)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
266
297
|
|
267
|
-
def
|
268
|
-
|
298
|
+
def fetch_corresponding_local_resources(remote_resources)
|
299
|
+
conditions = Array.wrap(remote_key).each_with_object({}) do |remote_attr, query|
|
300
|
+
local_attr = local_attribute_name(remote_attr)
|
301
|
+
query[local_attr] = remote_resources.map(&remote_attr)
|
302
|
+
end
|
303
|
+
|
304
|
+
where(conditions)
|
269
305
|
end
|
270
306
|
|
271
307
|
|
272
308
|
|
273
|
-
|
274
|
-
# Skip this for ActiveResource because it won't define a method until it has
|
275
|
-
# loaded an JSON for that method
|
276
|
-
return if model.is_a?(Class) and (model < ActiveResource::Base)
|
277
|
-
|
278
|
-
instance = model.new_resource
|
279
|
-
attr_getters_and_setters = remote_attribute_names + remote_attribute_names.map {|attr| :"#{attr}="}
|
280
|
-
unless instance.respond_to_all?(attr_getters_and_setters)
|
281
|
-
raise InvalidRemoteModel,
|
282
|
-
"#{instance.class} does not respond to getters and setters " <<
|
283
|
-
"for each remote attribute (not implemented: #{instance.does_not_respond_to(attr_getters_and_setters).sort.join(", ")}).\n"
|
284
|
-
end
|
285
|
-
end
|
309
|
+
private
|
286
310
|
|
311
|
+
def default_remote_attributes
|
312
|
+
column_names - %w{id created_at updated_at expires_at}
|
313
|
+
end
|
287
314
|
|
288
315
|
|
289
316
|
def generate_default_remote_key
|
@@ -293,7 +320,6 @@ module Remotable
|
|
293
320
|
end
|
294
321
|
|
295
322
|
|
296
|
-
|
297
323
|
def new_from_remote(remote_resource)
|
298
324
|
record = self.new
|
299
325
|
record.instance_variable_set(:@remote_resource, remote_resource)
|
@@ -313,7 +339,6 @@ module Remotable
|
|
313
339
|
:local_attribute_names,
|
314
340
|
:local_attribute_name,
|
315
341
|
:expires_after,
|
316
|
-
:find_remote_resource_by,
|
317
342
|
:to => "self.class"
|
318
343
|
|
319
344
|
def expired?
|
@@ -360,6 +385,14 @@ module Remotable
|
|
360
385
|
fetch_value && find_remote_resource_by(remote_key, fetch_value)
|
361
386
|
end
|
362
387
|
|
388
|
+
def find_remote_resource_by(remote_key, fetch_value)
|
389
|
+
if remote_model.respond_to?(:find_by_for_local)
|
390
|
+
remote_model.find_by_for_local(self, remote_key, fetch_value)
|
391
|
+
else
|
392
|
+
self.class.find_remote_resource_by(remote_key, fetch_value)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
363
396
|
def merge_remote_data!(remote_resource)
|
364
397
|
merge_remote_data(remote_resource)
|
365
398
|
reset_expiration_date
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Remotable
|
2
|
+
class NullRemote
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
# This is always invoked by instance#fetch_remote_resource.
|
7
|
+
# It expects to find a remote counterpart for a local resource.
|
8
|
+
# It should always return a NullRemote object that doesn't
|
9
|
+
# alter the behavior of a normal model at all.
|
10
|
+
def find_by_for_local(local_record, remote_key, fetch_value)
|
11
|
+
new
|
12
|
+
end
|
13
|
+
|
14
|
+
# This is always invoked via class#find_remote_resource_by
|
15
|
+
# by class#fetch_by. It gives the remote model an opportunity
|
16
|
+
# to discover a remote object that doesn't have a local
|
17
|
+
# counterpart. NullRemote should never discover something
|
18
|
+
# that doesn't exist locally.
|
19
|
+
def find_by(remote_attr, value)
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def new_resource
|
24
|
+
new
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# NullRemote needs to receive setter messages and
|
31
|
+
# swallow them. It doesn't need to respond to getter
|
32
|
+
# messages since it has nothing to say.
|
33
|
+
def method_missing(method_name, *args)
|
34
|
+
super unless method_name.to_s =~ /=$/
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def save
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def errors
|
43
|
+
{}
|
44
|
+
end
|
45
|
+
|
46
|
+
def destroy
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/lib/remotable/version.rb
CHANGED
data/lib/remotable.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "remotable/version"
|
2
2
|
require "remotable/nosync"
|
3
|
+
require "remotable/null_remote"
|
3
4
|
require "remotable/validate_models"
|
4
5
|
require "remotable/with_remote_model_proxy"
|
5
6
|
|
@@ -59,17 +60,18 @@ module Remotable
|
|
59
60
|
# <tt>model</tt> can be any object that responds
|
60
61
|
# to these two methods for getting a resource:
|
61
62
|
#
|
63
|
+
# * +new_resource+
|
62
64
|
# * +find_by(path)+ or +find_by(remote_attr, value)+
|
63
65
|
# +find_by+ can be defined to take either one argument or two.
|
64
66
|
# If it takes one argument, it will be passed path.
|
65
67
|
# If it takes two, it will be passed remote_attr and value.
|
66
|
-
# * +
|
68
|
+
# * (Optional) +find_by_for_local(local_record, remote_key, fetch_value)+
|
67
69
|
#
|
68
70
|
# Resources must respond to:
|
69
71
|
#
|
70
72
|
# * +save+ (return true on success and false on failure)
|
71
73
|
# * +destroy+
|
72
|
-
# * +errors+ (
|
74
|
+
# * +errors+ (returns a hash of error messages by attribute)
|
73
75
|
# * getters and setters for each attribute
|
74
76
|
#
|
75
77
|
def remote_model(*args)
|
data/remotable.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.add_development_dependency "rails"
|
21
21
|
s.add_development_dependency "minitest"
|
22
22
|
s.add_development_dependency "turn"
|
23
|
+
s.add_development_dependency "pry"
|
23
24
|
s.add_development_dependency "factory_girl"
|
24
25
|
s.add_development_dependency "sqlite3"
|
25
26
|
s.add_development_dependency "active_resource_simulator"
|
@@ -333,4 +333,36 @@ class ActiveResourceTest < ActiveSupport::TestCase
|
|
333
333
|
|
334
334
|
|
335
335
|
|
336
|
+
# ========================================================================= #
|
337
|
+
# Listing #
|
338
|
+
# ========================================================================= #
|
339
|
+
|
340
|
+
test "should be able to find all remote resources and sync them with local resources" do
|
341
|
+
tenant = Factory(:tenant, :expires_at => 1.year.ago)
|
342
|
+
|
343
|
+
assert_equal 1, Tenant.count, "There's supposed to be 1 tenant"
|
344
|
+
|
345
|
+
# Creates 1 missing resources, updates 1
|
346
|
+
assert_difference "Tenant.count", +1 do
|
347
|
+
RemoteTenant.run_simulation do |s|
|
348
|
+
s.show(nil, [
|
349
|
+
{ :id => tenant.id,
|
350
|
+
:slug => "a-different-slug",
|
351
|
+
:church_name => "A Different Name" },
|
352
|
+
{ :id => tenant.id + 1,
|
353
|
+
:slug => "generic-slug",
|
354
|
+
:church_name => "Generic Name" }],
|
355
|
+
:path => "/api/accounts.json")
|
356
|
+
|
357
|
+
tenants = Tenant.all_by_remote
|
358
|
+
assert_equal 2, tenants.length
|
359
|
+
|
360
|
+
assert_equal "a-different-slug", tenant.reload.slug
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
|
366
|
+
|
367
|
+
|
336
368
|
end
|
data/test/factories/tenants.rb
CHANGED
@@ -13,3 +13,11 @@ Factory.define :bespoke_tenant do |f|
|
|
13
13
|
f.expires_at 100.years.from_now
|
14
14
|
f.nosync true
|
15
15
|
end
|
16
|
+
|
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
|
+
end
|
data/test/nosync_test.rb
CHANGED
@@ -27,4 +27,19 @@ class NoSyncTest < ActiveSupport::TestCase
|
|
27
27
|
|
28
28
|
|
29
29
|
|
30
|
+
# ========================================================================= #
|
31
|
+
# Finding #
|
32
|
+
# ========================================================================= #
|
33
|
+
|
34
|
+
test "should do nothing if a tenant is expired" do
|
35
|
+
tenant = Factory(:tenant, :expires_at => 1.year.ago)
|
36
|
+
|
37
|
+
Remotable.nosync do
|
38
|
+
result = Tenant.find_by_remote_id(tenant.remote_id)
|
39
|
+
assert_equal tenant, result
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
30
45
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "remotable"
|
3
|
+
require "support/null"
|
4
|
+
|
5
|
+
|
6
|
+
class NullRemoteTest < ActiveSupport::TestCase
|
7
|
+
include RR::Adapters::TestUnit
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
# ========================================================================= #
|
12
|
+
# Finding #
|
13
|
+
# ========================================================================= #
|
14
|
+
|
15
|
+
test "should do nothing if a tenant is expired" do
|
16
|
+
tenant = Factory(:null_test_tenant, expires_at: 2.days.ago)
|
17
|
+
result = NullTestTenant.find_by_slug(tenant.slug)
|
18
|
+
assert_equal tenant, result
|
19
|
+
end
|
20
|
+
|
21
|
+
test "should raise an exception with the bang method if resource isn't found locally" do
|
22
|
+
new_tenant_slug = "not_found3"
|
23
|
+
assert_equal 0, NullTestTenant.where(:slug => new_tenant_slug).count,
|
24
|
+
"There's not supposed to be a NullTestTenant with the slug #{new_tenant_slug}."
|
25
|
+
|
26
|
+
assert_raises ActiveRecord::RecordNotFound do
|
27
|
+
NullTestTenant.find_by_slug!(new_tenant_slug)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
# ========================================================================= #
|
34
|
+
# Updating #
|
35
|
+
# ========================================================================= #
|
36
|
+
|
37
|
+
test "should update a record locally without any interference" do
|
38
|
+
tenant = Factory(:null_test_tenant)
|
39
|
+
new_name = "Totally Wonky"
|
40
|
+
|
41
|
+
tenant.name = new_name
|
42
|
+
tenant.save!
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
# ========================================================================= #
|
48
|
+
# Creating #
|
49
|
+
# ========================================================================= #
|
50
|
+
|
51
|
+
test "should create a record locally without any interference" do
|
52
|
+
tenant = NullTestTenant.create!({
|
53
|
+
:slug => "brand_new",
|
54
|
+
:name => "Brand New"
|
55
|
+
})
|
56
|
+
assert_not_nil tenant.remote_resource
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
# ========================================================================= #
|
62
|
+
# Destroying #
|
63
|
+
# ========================================================================= #
|
64
|
+
|
65
|
+
test "should destroy a record locally without any interference" do
|
66
|
+
tenant = Factory(:null_test_tenant)
|
67
|
+
tenant.nosync = false
|
68
|
+
tenant.destroy
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
end
|
data/test/remotable_test.rb
CHANGED
@@ -79,7 +79,6 @@ class RemotableTest < ActiveSupport::TestCase
|
|
79
79
|
|
80
80
|
# Fetching this tenant, Remotable will want to
|
81
81
|
# refresh it, but it shouldn't because it can't.
|
82
|
-
puts "->"
|
83
82
|
assert_not_nil Tenant.where(:slug => "test-1").first, "A tenant with the slug \"test-1\" was not found"
|
84
83
|
end
|
85
84
|
|
@@ -127,27 +126,27 @@ class RemotableTest < ActiveSupport::TestCase
|
|
127
126
|
# ========================================================================= #
|
128
127
|
|
129
128
|
test "should raise an exception if a remote model does not respond to all class methods" do
|
130
|
-
class Example1 < ActiveRecord::Base;
|
129
|
+
class Example1 < ActiveRecord::Base; self.table_name = "tenants"; end
|
131
130
|
class RemoteModel1; def self.find_by(*args); end; end
|
132
131
|
assert_raise(Remotable::InvalidRemoteModel) { Example1.remote_model RemoteModel1 }
|
133
132
|
end
|
134
133
|
|
135
134
|
test "should raise an exception if a remote resource does not respond to all instance methods" do
|
136
|
-
class Example2 < ActiveRecord::Base;
|
135
|
+
class Example2 < ActiveRecord::Base; self.table_name = "tenants"; end
|
137
136
|
class RemoteModel2; def self.new_resource; Object.new; end; end
|
138
137
|
assert_raise(Remotable::InvalidRemoteModel) { Example2.remote_model RemoteModel2 }
|
139
138
|
end
|
140
139
|
|
141
140
|
test "should not raise an exception if remote models are not being validated" do
|
142
141
|
Remotable.without_validation do
|
143
|
-
class Example4 < ActiveRecord::Base;
|
142
|
+
class Example4 < ActiveRecord::Base; self.table_name = "tenants"; end
|
144
143
|
class RemoteModel4; def self.find_by(*args); end; end
|
145
144
|
assert_nothing_raised { Example4.remote_model RemoteModel4 }
|
146
145
|
end
|
147
146
|
end
|
148
147
|
|
149
148
|
test "should not raise an exception if a remote model responds to all required methods" do
|
150
|
-
class Example3 < ActiveRecord::Base;
|
149
|
+
class Example3 < ActiveRecord::Base; self.table_name = "tenants"; end
|
151
150
|
assert_nothing_raised { Example3.remote_model BespokeModel.new }
|
152
151
|
end
|
153
152
|
|
@@ -21,14 +21,14 @@ class Tenant < ActiveRecord::Base
|
|
21
21
|
end
|
22
22
|
|
23
23
|
class RemoteWithoutKey < ActiveRecord::Base
|
24
|
-
|
24
|
+
self.table_name = "tenants"
|
25
25
|
|
26
26
|
remote_model RemoteTenant
|
27
27
|
attr_remote :id => :remote_id
|
28
28
|
end
|
29
29
|
|
30
30
|
class RemoteWithKey < ActiveRecord::Base
|
31
|
-
|
31
|
+
self.table_name = "tenants"
|
32
32
|
|
33
33
|
remote_model RemoteTenant
|
34
34
|
attr_remote :slug
|
@@ -36,7 +36,7 @@ class RemoteWithKey < ActiveRecord::Base
|
|
36
36
|
end
|
37
37
|
|
38
38
|
class RemoteWithCompositeKey < ActiveRecord::Base
|
39
|
-
|
39
|
+
self.table_name = "tenants"
|
40
40
|
|
41
41
|
remote_model RemoteTenant
|
42
42
|
attr_remote :group_id, :slug
|
data/test/support/bespoke.rb
CHANGED
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,206 +1,195 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remotable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Robert Lail
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-03-18 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activeresource
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: activerecord
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: activesupport
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: rails
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: minitest
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: turn
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - '>='
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
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
|
+
- - '>='
|
108
109
|
- !ruby/object:Gem::Version
|
109
110
|
version: '0'
|
110
111
|
- !ruby/object:Gem::Dependency
|
111
112
|
name: factory_girl
|
112
113
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - '>='
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
121
|
requirements:
|
123
|
-
- -
|
122
|
+
- - '>='
|
124
123
|
- !ruby/object:Gem::Version
|
125
124
|
version: '0'
|
126
125
|
- !ruby/object:Gem::Dependency
|
127
126
|
name: sqlite3
|
128
127
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
128
|
requirements:
|
131
|
-
- -
|
129
|
+
- - '>='
|
132
130
|
- !ruby/object:Gem::Version
|
133
131
|
version: '0'
|
134
132
|
type: :development
|
135
133
|
prerelease: false
|
136
134
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
135
|
requirements:
|
139
|
-
- -
|
136
|
+
- - '>='
|
140
137
|
- !ruby/object:Gem::Version
|
141
138
|
version: '0'
|
142
139
|
- !ruby/object:Gem::Dependency
|
143
140
|
name: active_resource_simulator
|
144
141
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
142
|
requirements:
|
147
|
-
- -
|
143
|
+
- - '>='
|
148
144
|
- !ruby/object:Gem::Version
|
149
145
|
version: '0'
|
150
146
|
type: :development
|
151
147
|
prerelease: false
|
152
148
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
149
|
requirements:
|
155
|
-
- -
|
150
|
+
- - '>='
|
156
151
|
- !ruby/object:Gem::Version
|
157
152
|
version: '0'
|
158
153
|
- !ruby/object:Gem::Dependency
|
159
154
|
name: simplecov
|
160
155
|
requirement: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
156
|
requirements:
|
163
|
-
- -
|
157
|
+
- - '>='
|
164
158
|
- !ruby/object:Gem::Version
|
165
159
|
version: '0'
|
166
160
|
type: :development
|
167
161
|
prerelease: false
|
168
162
|
version_requirements: !ruby/object:Gem::Requirement
|
169
|
-
none: false
|
170
163
|
requirements:
|
171
|
-
- -
|
164
|
+
- - '>='
|
172
165
|
- !ruby/object:Gem::Version
|
173
166
|
version: '0'
|
174
167
|
- !ruby/object:Gem::Dependency
|
175
168
|
name: rr
|
176
169
|
requirement: !ruby/object:Gem::Requirement
|
177
|
-
none: false
|
178
170
|
requirements:
|
179
|
-
- -
|
171
|
+
- - '>='
|
180
172
|
- !ruby/object:Gem::Version
|
181
173
|
version: '0'
|
182
174
|
type: :development
|
183
175
|
prerelease: false
|
184
176
|
version_requirements: !ruby/object:Gem::Requirement
|
185
|
-
none: false
|
186
177
|
requirements:
|
187
|
-
- -
|
178
|
+
- - '>='
|
188
179
|
- !ruby/object:Gem::Version
|
189
180
|
version: '0'
|
190
181
|
- !ruby/object:Gem::Dependency
|
191
182
|
name: database_cleaner
|
192
183
|
requirement: !ruby/object:Gem::Requirement
|
193
|
-
none: false
|
194
184
|
requirements:
|
195
|
-
- -
|
185
|
+
- - '>='
|
196
186
|
- !ruby/object:Gem::Version
|
197
187
|
version: '0'
|
198
188
|
type: :development
|
199
189
|
prerelease: false
|
200
190
|
version_requirements: !ruby/object:Gem::Requirement
|
201
|
-
none: false
|
202
191
|
requirements:
|
203
|
-
- -
|
192
|
+
- - '>='
|
204
193
|
- !ruby/object:Gem::Version
|
205
194
|
version: '0'
|
206
195
|
description: Remotable keeps a locally-stored ActiveRecord synchronized with a remote
|
@@ -214,6 +203,7 @@ files:
|
|
214
203
|
- .gitignore
|
215
204
|
- .simplecov
|
216
205
|
- Gemfile
|
206
|
+
- Gemfile.lock
|
217
207
|
- MIT-LICENSE
|
218
208
|
- README.mdown
|
219
209
|
- Rakefile
|
@@ -226,6 +216,7 @@ files:
|
|
226
216
|
- lib/remotable/core_ext/object.rb
|
227
217
|
- lib/remotable/core_ext/uri.rb
|
228
218
|
- lib/remotable/nosync.rb
|
219
|
+
- lib/remotable/null_remote.rb
|
229
220
|
- lib/remotable/validate_models.rb
|
230
221
|
- lib/remotable/version.rb
|
231
222
|
- lib/remotable/with_remote_model_proxy.rb
|
@@ -234,50 +225,47 @@ files:
|
|
234
225
|
- test/bespoke_test.rb
|
235
226
|
- test/factories/tenants.rb
|
236
227
|
- test/nosync_test.rb
|
228
|
+
- test/null_remote_test.rb
|
237
229
|
- test/remotable_test.rb
|
238
230
|
- test/support/active_resource.rb
|
239
231
|
- test/support/bespoke.rb
|
232
|
+
- test/support/null.rb
|
240
233
|
- test/support/schema.rb
|
241
234
|
- test/test_helper.rb
|
242
235
|
- test/understanding_test.rb
|
243
236
|
homepage: ''
|
244
237
|
licenses: []
|
238
|
+
metadata: {}
|
245
239
|
post_install_message:
|
246
240
|
rdoc_options: []
|
247
241
|
require_paths:
|
248
242
|
- lib
|
249
243
|
required_ruby_version: !ruby/object:Gem::Requirement
|
250
|
-
none: false
|
251
244
|
requirements:
|
252
|
-
- -
|
245
|
+
- - '>='
|
253
246
|
- !ruby/object:Gem::Version
|
254
247
|
version: '0'
|
255
|
-
segments:
|
256
|
-
- 0
|
257
|
-
hash: 3994390182043534799
|
258
248
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
259
|
-
none: false
|
260
249
|
requirements:
|
261
|
-
- -
|
250
|
+
- - '>='
|
262
251
|
- !ruby/object:Gem::Version
|
263
252
|
version: '0'
|
264
|
-
segments:
|
265
|
-
- 0
|
266
|
-
hash: 3994390182043534799
|
267
253
|
requirements: []
|
268
254
|
rubyforge_project: remotable
|
269
|
-
rubygems_version:
|
255
|
+
rubygems_version: 2.0.0
|
270
256
|
signing_key:
|
271
|
-
specification_version:
|
257
|
+
specification_version: 4
|
272
258
|
summary: Binds an ActiveRecord model to a remote resource and keeps the two synchronized
|
273
259
|
test_files:
|
274
260
|
- test/active_resource_test.rb
|
275
261
|
- test/bespoke_test.rb
|
276
262
|
- test/factories/tenants.rb
|
277
263
|
- test/nosync_test.rb
|
264
|
+
- test/null_remote_test.rb
|
278
265
|
- test/remotable_test.rb
|
279
266
|
- test/support/active_resource.rb
|
280
267
|
- test/support/bespoke.rb
|
268
|
+
- test/support/null.rb
|
281
269
|
- test/support/schema.rb
|
282
270
|
- test/test_helper.rb
|
283
271
|
- test/understanding_test.rb
|