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 CHANGED
@@ -1,5 +1,6 @@
1
1
  require "arrest/version"
2
2
 
3
+ require "arrest/attributes/belongs_to"
3
4
  require "arrest/attributes/has_attributes"
4
5
  require "arrest/attributes/converter"
5
6
  require "arrest/source"
@@ -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
- resolved_class.new value
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 resolved_class
37
- if @clazz == nil
38
- @clazz = Source.mod.const_get(@clazz_name)
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
@@ -4,6 +4,7 @@ module Arrest
4
4
  # an other NestedResource
5
5
  class NestedResource
6
6
  include HasAttributes
7
+ include BelongsTo
7
8
 
8
9
  def initialize h
9
10
  init_from_hash h
@@ -28,6 +28,10 @@ module Arrest
28
28
  end
29
29
  end
30
30
 
31
+ def find id
32
+ raise "find cannot be executed for child resources - use find_for with a parent"
33
+ end
34
+
31
35
  def find_for parent,id
32
36
  r = source().get_one "#{self.resource_path_for(parent)}/#{id}"
33
37
  body = body_root(r)
@@ -45,7 +45,8 @@ class StringUtils
45
45
  def classify(str, upper_first = true)
46
46
  result = ""
47
47
  upperNext = false
48
- (singular str) .each_char do |c|
48
+ #(singular str) .each_char do |c|
49
+ (str) .each_char do |c|
49
50
  if c == "_"
50
51
  upperNext = true
51
52
  else
@@ -1,3 +1,3 @@
1
1
  module Arrest
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
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
@@ -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.6
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-02 00:00:00.000000000Z
12
+ date: 2011-12-05 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
16
- requirement: &2162431160 !ruby/object:Gem::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: *2162431160
24
+ version_requirements: *2154189380
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: faraday
27
- requirement: &2162430460 !ruby/object:Gem::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: *2162430460
35
+ version_requirements: *2154188840
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bundler
38
- requirement: &2162429700 !ruby/object:Gem::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: *2162429700
46
+ version_requirements: *2154188080
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
- requirement: &2162428760 !ruby/object:Gem::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: *2162428760
57
+ version_requirements: *2154187220
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rdoc
60
- requirement: &2162427040 !ruby/object:Gem::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: *2162427040
68
+ version_requirements: *2154186100
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &2162426160 !ruby/object:Gem::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: *2162426160
79
+ version_requirements: *2154185300
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rr
82
- requirement: &2162425700 !ruby/object:Gem::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: *2162425700
90
+ version_requirements: *2154184880
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: simplecov
93
- requirement: &2162425100 !ruby/object:Gem::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: *2162425100
101
+ version_requirements: *2154184380
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: rack
104
- requirement: &2162424460 !ruby/object:Gem::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: *2162424460
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