arrest 0.0.6 → 0.0.7
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.
- data/lib/arrest.rb +1 -0
- data/lib/arrest/abstract_resource.rb +5 -11
- data/lib/arrest/attributes/belongs_to.rb +32 -0
- data/lib/arrest/attributes/converter.rb +13 -5
- data/lib/arrest/attributes/has_attributes.rb +16 -0
- data/lib/arrest/nested_resource.rb +1 -0
- data/lib/arrest/rest_child.rb +4 -0
- data/lib/arrest/string_utils.rb +2 -1
- data/lib/arrest/version.rb +1 -1
- data/test/models.rb +25 -0
- data/test/nested_resource.rb +91 -1
- metadata +21 -20
data/lib/arrest.rb
CHANGED
@@ -64,7 +64,7 @@ module Arrest
|
|
64
64
|
@child_collections = {}
|
65
65
|
end
|
66
66
|
if @child_collections[method_name] == nil
|
67
|
-
@child_collections[method_name] = ChildCollection.new(self, (StringUtils.classify clazz_name))
|
67
|
+
@child_collections[method_name] = ChildCollection.new(self, (StringUtils.classify (StringUtils.singular clazz_name)))
|
68
68
|
end
|
69
69
|
|
70
70
|
@child_collections[method_name]
|
@@ -92,18 +92,10 @@ module Arrest
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
def belongs_to(*args)
|
96
|
-
arg = args[0]
|
97
|
-
name = arg.to_s.downcase
|
98
|
-
attributes({"#{name}_id".to_sym => String})
|
99
|
-
send :define_method, name do
|
100
|
-
val = self.instance_variable_get("@#{name}_id")
|
101
|
-
Arrest::Source.mod.const_get(StringUtils.classify name).find(val)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
95
|
end
|
106
96
|
|
97
|
+
include BelongsTo
|
98
|
+
|
107
99
|
attr_accessor :id
|
108
100
|
attr_reader :stub
|
109
101
|
|
@@ -132,6 +124,8 @@ module Arrest
|
|
132
124
|
val = self.instance_variable_get("@#{field.name.to_s}")
|
133
125
|
if val != nil && val.is_a?(NestedResource)
|
134
126
|
val = val.to_hash
|
127
|
+
elsif val != nil && field.is_a?(NestedCollection)
|
128
|
+
val = val.map {|v| v.to_hash}
|
135
129
|
end
|
136
130
|
result[json_name] = val
|
137
131
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Arrest
|
2
|
+
# Manages an id field of an external resource referenced by this resource.
|
3
|
+
# Provides accessor to load exteral resource.
|
4
|
+
module BelongsTo
|
5
|
+
def self.included(base) # :nodoc:
|
6
|
+
base.extend BelongsToMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module BelongsToMethods
|
10
|
+
def belongs_to(*args)
|
11
|
+
arg = args[0]
|
12
|
+
name = arg.to_s.downcase
|
13
|
+
class_name = StringUtils.classify name
|
14
|
+
params = args[1] unless args.length < 2
|
15
|
+
field_name = "#{name}_id"
|
16
|
+
if params
|
17
|
+
field_name = params[:field_name] unless params[:field_name] == nil
|
18
|
+
class_name = params[:class_name].to_s unless params[:class_name] == nil
|
19
|
+
end
|
20
|
+
attributes({field_name.to_sym => String})
|
21
|
+
send :define_method, name do
|
22
|
+
val = self.send(field_name)
|
23
|
+
begin
|
24
|
+
Arrest::Source.mod.const_get(class_name).find(val)
|
25
|
+
rescue Errors::DocumentNotFoundError => e
|
26
|
+
raise Errors::DocumentNotFoundError, "Couldnt find a #{class_name} with id #{val}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -30,15 +30,23 @@ module Arrest
|
|
30
30
|
|
31
31
|
def convert value
|
32
32
|
return unless value
|
33
|
-
|
33
|
+
@clazz.new value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class NestedCollection < Attribute
|
38
|
+
def initialize name, read_only, clazz
|
39
|
+
super name, read_only, clazz
|
34
40
|
end
|
35
41
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
42
|
+
def convert value
|
43
|
+
return unless value
|
44
|
+
raise "Expected an array but got #{value.class.name}" unless value.is_a?(Array)
|
45
|
+
value.map do |v|
|
46
|
+
@clazz.new v
|
39
47
|
end
|
40
|
-
@clazz
|
41
48
|
end
|
49
|
+
|
42
50
|
end
|
43
51
|
|
44
52
|
CONVERTER = {}
|
@@ -92,6 +92,22 @@ module Arrest
|
|
92
92
|
|
93
93
|
end
|
94
94
|
|
95
|
+
def nested_array name, clazz
|
96
|
+
add_attribute NestedCollection.new(name, false, clazz)
|
97
|
+
|
98
|
+
send :define_method, "#{name}=" do |v|
|
99
|
+
self.unstub
|
100
|
+
self.instance_variable_set("@#{name}", v)
|
101
|
+
end
|
102
|
+
send :define_method, "#{name}" do
|
103
|
+
self.unstub
|
104
|
+
self.instance_variable_get("@#{name}")
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
95
109
|
end
|
110
|
+
|
111
|
+
|
96
112
|
end
|
97
113
|
end
|
data/lib/arrest/rest_child.rb
CHANGED
data/lib/arrest/string_utils.rb
CHANGED
data/lib/arrest/version.rb
CHANGED
data/test/models.rb
CHANGED
@@ -41,3 +41,28 @@ class WithNested < Arrest::RootResource
|
|
41
41
|
nested :nested_object, ANestedClass
|
42
42
|
end
|
43
43
|
|
44
|
+
class WithManyNested < Arrest::RootResource
|
45
|
+
attribute :parent_name, String
|
46
|
+
attribute :bool, Boolean
|
47
|
+
nested_array :nested_objects, ANestedClass
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
class ANestedClassBelonging < Arrest::NestedResource
|
52
|
+
attribute :name, String
|
53
|
+
attribute :bool, Boolean
|
54
|
+
|
55
|
+
belongs_to :zoo
|
56
|
+
end
|
57
|
+
|
58
|
+
class WithNestedBelongingTo < Arrest::RootResource
|
59
|
+
attribute :parent_name, String
|
60
|
+
attribute :bool, Boolean
|
61
|
+
nested :nested_object, ANestedClassBelonging
|
62
|
+
end
|
63
|
+
|
64
|
+
class CustomNamedBelongsTo < Arrest::RootResource
|
65
|
+
attribute :name, String
|
66
|
+
belongs_to :zoo_thing, { :field_name => :schinken, :class_name => :Zoo}
|
67
|
+
belongs_to :zoo, { :field_name => :batzen}
|
68
|
+
end
|
data/test/nested_resource.rb
CHANGED
@@ -26,7 +26,6 @@ class NestedResourcesTest < Test::Unit::TestCase
|
|
26
26
|
actual = WithNested.new(input)
|
27
27
|
assert_equal 'parent', actual.parent_name
|
28
28
|
assert_equal false, actual.bool
|
29
|
-
puts actual.inspect
|
30
29
|
assert actual.respond_to? :nested_object, "The parent object should have an accessor for the nested object"
|
31
30
|
assert_equal 'iamnested', actual.nested_object.name
|
32
31
|
assert_equal true, actual.nested_object.bool
|
@@ -58,6 +57,97 @@ class NestedResourcesTest < Test::Unit::TestCase
|
|
58
57
|
|
59
58
|
end
|
60
59
|
|
60
|
+
def test_many_to_hash
|
61
|
+
input = {
|
62
|
+
:parent_name => 'parent',
|
63
|
+
:bool => false,
|
64
|
+
:nested_objects => [
|
65
|
+
{
|
66
|
+
:name => 'iamnested_one',
|
67
|
+
:bool => true
|
68
|
+
},{
|
69
|
+
:name => 'iamnested_two',
|
70
|
+
:bool => false
|
71
|
+
}
|
72
|
+
]
|
73
|
+
}
|
74
|
+
|
75
|
+
actual = WithManyNested.new(input)
|
76
|
+
|
77
|
+
# we expect camel cased keys
|
78
|
+
expected = {
|
79
|
+
'parentName' => 'parent',
|
80
|
+
'bool' => false,
|
81
|
+
'nestedObjects' => [
|
82
|
+
{
|
83
|
+
'name' => 'iamnested_one',
|
84
|
+
'bool' => true
|
85
|
+
},{
|
86
|
+
'name' => 'iamnested_two',
|
87
|
+
'bool' => false
|
88
|
+
}
|
89
|
+
]
|
90
|
+
}
|
91
|
+
|
92
|
+
assert_equal_hashes expected, actual.to_hash
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_belongd_to_to_hash
|
97
|
+
new_zoo = Zoo.new({:name => "Foo"})
|
98
|
+
new_zoo.save
|
99
|
+
|
100
|
+
input = {
|
101
|
+
:parent_name => 'parent',
|
102
|
+
:bool => false,
|
103
|
+
:nested_object => {
|
104
|
+
:name => 'iamnested',
|
105
|
+
:bool => true,
|
106
|
+
:zoo_id => new_zoo.id
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
actual = WithNestedBelongingTo.new(input)
|
111
|
+
|
112
|
+
# we expect camel cased keys
|
113
|
+
expected = {
|
114
|
+
'parentName' => 'parent',
|
115
|
+
'bool' => false,
|
116
|
+
'nestedObject' => {
|
117
|
+
'name' => 'iamnested',
|
118
|
+
'bool' => true,
|
119
|
+
'zooId' => new_zoo.id
|
120
|
+
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
assert_equal_hashes expected, actual.to_hash
|
125
|
+
|
126
|
+
zoo = actual.nested_object.zoo
|
127
|
+
assert_equal "Foo", zoo.name
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_custom_belongs_to
|
132
|
+
|
133
|
+
new_zoo = Zoo.new({:name => "Foo"})
|
134
|
+
new_zoo.save
|
135
|
+
|
136
|
+
c = CustomNamedBelongsTo.new({:name => 'Bar', :schinken => new_zoo.id, :batzen => new_zoo.id})
|
137
|
+
|
138
|
+
c.save
|
139
|
+
assert_not_nil c.id, "Persisted object should have id"
|
140
|
+
assert_equal "Foo", c.zoo_thing.name
|
141
|
+
assert_equal "Foo", c.zoo.name
|
142
|
+
|
143
|
+
|
144
|
+
assert_not_nil c.id, "Persisted zoo should have id"
|
145
|
+
c_reloaded = CustomNamedBelongsTo.all.first
|
146
|
+
assert_equal "Foo", c_reloaded.zoo_thing.name
|
147
|
+
assert_equal "Foo", c_reloaded.zoo.name
|
148
|
+
|
149
|
+
end
|
150
|
+
|
61
151
|
def assert_equal_hashes expected, actual
|
62
152
|
assert_equal_hashes_ expected, actual, ''
|
63
153
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arrest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-05 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
|
-
requirement: &
|
16
|
+
requirement: &2154189380 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2154189380
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: faraday
|
27
|
-
requirement: &
|
27
|
+
requirement: &2154188840 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - =
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.7.5
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2154188840
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: bundler
|
38
|
-
requirement: &
|
38
|
+
requirement: &2154188080 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.0.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2154188080
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
|
-
requirement: &
|
49
|
+
requirement: &2154187220 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2154187220
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rdoc
|
60
|
-
requirement: &
|
60
|
+
requirement: &2154186100 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2154186100
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
|
-
requirement: &
|
71
|
+
requirement: &2154185300 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '2'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *2154185300
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rr
|
82
|
-
requirement: &
|
82
|
+
requirement: &2154184880 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *2154184880
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: simplecov
|
93
|
-
requirement: &
|
93
|
+
requirement: &2154184380 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: '0'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *2154184380
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: rack
|
104
|
-
requirement: &
|
104
|
+
requirement: &2154183740 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ! '>='
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
version: '0'
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *2154183740
|
113
113
|
description: Consume a rest API in a AR like fashion
|
114
114
|
email:
|
115
115
|
- axel.tetzlaff@fortytools.com
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- arrest.gemspec
|
126
126
|
- lib/arrest.rb
|
127
127
|
- lib/arrest/abstract_resource.rb
|
128
|
+
- lib/arrest/attributes/belongs_to.rb
|
128
129
|
- lib/arrest/attributes/converter.rb
|
129
130
|
- lib/arrest/attributes/has_attributes.rb
|
130
131
|
- lib/arrest/exceptions.rb
|