arke 0.0.5 → 0.1.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 +4 -4
- data/lib/arke/resource.rb +8 -1
- data/lib/arke/resource/associations.rb +79 -2
- data/lib/arke/resource/callbacks.rb +48 -0
- data/lib/arke/resource/collection.rb +5 -1
- data/lib/arke/resource/collections.rb +21 -0
- data/lib/arke/resource/finders.rb +22 -0
- data/lib/arke/resource/model.rb +19 -190
- data/lib/arke/resource/naming.rb +24 -0
- data/lib/arke/resource/persistence.rb +88 -0
- data/lib/arke/resource/requests.rb +77 -0
- data/lib/arke/resource/url.rb +63 -0
- data/lib/arke/version.rb +2 -2
- metadata +9 -4
- data/lib/arke/resource/associations/base.rb +0 -27
- data/lib/arke/resource/associations/has_many_association.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a479182f0944a9b4041d8824b676b584e11a0aa8
|
4
|
+
data.tar.gz: 7a792983ca76b4dc5ffd1cc49b0efe5f136be516
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b355fa1a09f486c2185a354b9884345be3a32ae208925fd6d1a2b6072c52a7c8a16bfe07e445e7b678723107a84c8ab205308d132b03da3e9dd137a9301e1d90
|
7
|
+
data.tar.gz: ce01399d29ba4b73a745a2354155dd2cd7599b2da5f4065e71186dfd043ac80bf86c9801f74eb7e309e2198cf87fd97e715d5fe75677a69c8985f1caf0a78e4f
|
data/lib/arke/resource.rb
CHANGED
@@ -6,5 +6,12 @@ require 'addressable/template'
|
|
6
6
|
require 'arke/resource/errors'
|
7
7
|
require 'arke/resource/fields'
|
8
8
|
require 'arke/resource/collection'
|
9
|
-
require 'arke/resource/
|
9
|
+
require 'arke/resource/collections'
|
10
|
+
require 'arke/resource/persistence'
|
11
|
+
require 'arke/resource/callbacks'
|
10
12
|
require 'arke/resource/associations'
|
13
|
+
require 'arke/resource/requests'
|
14
|
+
require 'arke/resource/url'
|
15
|
+
require 'arke/resource/naming'
|
16
|
+
require 'arke/resource/finders'
|
17
|
+
require 'arke/resource/model'
|
@@ -1,2 +1,79 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Arke
|
2
|
+
module Resource
|
3
|
+
module Associations
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
TEMPLATES = {
|
7
|
+
:has_many => "/{parent_resource_name}/{relation_id}/{resource_name}"
|
8
|
+
}
|
9
|
+
|
10
|
+
included do |base|
|
11
|
+
base.class_eval do
|
12
|
+
class_attribute :associations
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
def belongs_to(name, options={})
|
22
|
+
# self.associations ||= {}
|
23
|
+
# self.associations[name] = {class: infer_class(name, options), options: options}
|
24
|
+
# define_method name do
|
25
|
+
# if self.persisted?
|
26
|
+
# instance_variable_set "@#{name}".to_sym, self.class.associations[name][:class].
|
27
|
+
# new(id: self.send("#{name}_id".to_sym)).reload unless instance_variable_get("@#{name}".to_sym)
|
28
|
+
# instance_variable_get("@#{name}".to_sym)
|
29
|
+
# else
|
30
|
+
# nil
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
end
|
34
|
+
|
35
|
+
def has_many(name, options={})
|
36
|
+
build_association(:has_many, name, '/{parent_resource_name}/{relation_id}/{resource_name}?{query*}', self._collection, options)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def build_association(type, name, template, klass, options)
|
42
|
+
self.associations ||= {}
|
43
|
+
self.associations[name] = {
|
44
|
+
template: (options[:template] || template),
|
45
|
+
class_name: infer_class_name(options.delete(:class_name)|| name.to_s.classify)
|
46
|
+
}.merge(options).merge({
|
47
|
+
type: type,
|
48
|
+
instance_class: klass
|
49
|
+
})
|
50
|
+
define_method name do
|
51
|
+
association = self.class.associations[name]
|
52
|
+
k = association[:class_name].constantize
|
53
|
+
set_instance_variable_if_nil("@#{name}", association[:instance_class].new(k, k.send(:get, {
|
54
|
+
_template: association[:template],
|
55
|
+
_relation_id: self.id,
|
56
|
+
_resource_name: k.resource_name,
|
57
|
+
_parent_resource_name: self.resource_name
|
58
|
+
})))
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def infer_class_name(class_name)
|
64
|
+
"#{self.name.split('::')[0..-2].unshift('').join('::')}::#{class_name}"
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
def set_instance_variable_if_nil(name, value)
|
71
|
+
instance_variable_set(name, value) unless instance_variable_get(name)
|
72
|
+
instance_variable_get(name)
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Arke
|
2
|
+
module Resource
|
3
|
+
module Callbacks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :after_initialize_callbacks
|
8
|
+
|
9
|
+
alias_method_chain :initialize, :after_initializers
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
|
16
|
+
def after_initialize(method=nil, &block)
|
17
|
+
self.after_initializers ||= []
|
18
|
+
if block_given?
|
19
|
+
self.after_initializers << block
|
20
|
+
else
|
21
|
+
self.after_initializers << method
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def initialize_with_after_initializers(attributes={})
|
30
|
+
initialize_without_after_initializers attributes
|
31
|
+
self.class.after_initialize_callbacks ||= []
|
32
|
+
self.class.after_initialize_callbacks.each do |callback|
|
33
|
+
execute_callback(callback, attributes)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def execute_callback(callback, *args)
|
38
|
+
if callback.is_a? Symbol
|
39
|
+
self.send(callback, *args)
|
40
|
+
else
|
41
|
+
callback.call(*args)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -3,10 +3,14 @@ module Arke
|
|
3
3
|
class Collection
|
4
4
|
include Enumerable
|
5
5
|
|
6
|
+
attr_reader :parent
|
7
|
+
delegate :delete_all, to: :parent
|
8
|
+
|
6
9
|
def initialize(parent, array)
|
7
10
|
raise Errors::UnexpectedResponse.
|
8
11
|
new("#all expected to receive an Array from the resource, instead a #{array.class} was received.") unless array.is_a? Array
|
9
|
-
@
|
12
|
+
@parent = parent
|
13
|
+
@array = array.collect { |item| @parent.new(item) }
|
10
14
|
end
|
11
15
|
|
12
16
|
def each(&block)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Arke
|
2
|
+
module Resource
|
3
|
+
module Collections
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :_collection
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
def collection(collection=nil)
|
13
|
+
self._collection = collection if collection
|
14
|
+
self._collection || Arke::Resource::Collection
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Arke
|
2
|
+
module Resource
|
3
|
+
module Finders
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
def find(id, params={})
|
9
|
+
body = get({id: id}.merge(params))
|
10
|
+
new(body)
|
11
|
+
end
|
12
|
+
|
13
|
+
def all(params={})
|
14
|
+
body = get(params)
|
15
|
+
self.collection.new(self, body)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/arke/resource/model.rb
CHANGED
@@ -4,227 +4,56 @@ module Arke
|
|
4
4
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
|
-
included do
|
8
|
-
|
9
|
-
|
10
|
-
include ActiveModel::Conversion
|
11
|
-
include ActiveModel::Validations
|
12
|
-
include HTTParty
|
7
|
+
included do
|
8
|
+
include ActiveModel
|
9
|
+
include ActiveModel::Conversion
|
13
10
|
|
14
|
-
|
11
|
+
extend ActiveModel::Naming
|
15
12
|
|
16
|
-
|
13
|
+
include Resource::Fields
|
14
|
+
include Resource::Associations
|
15
|
+
include Resource::Requests
|
16
|
+
include Resource::Collections
|
17
|
+
include Resource::URL
|
18
|
+
include Resource::Persistence
|
19
|
+
include Resource::Callbacks
|
20
|
+
include Resource::Naming
|
21
|
+
include Resource::Finders
|
17
22
|
|
18
|
-
|
23
|
+
deserializer { |body| JSON.parse(body) }
|
19
24
|
|
20
|
-
|
25
|
+
field :id, type: String
|
21
26
|
|
22
|
-
attr_accessor :associations, :after_initializers
|
23
27
|
|
24
|
-
end
|
25
|
-
|
26
|
-
collection Arke::Resource::Collection
|
27
|
-
url_template DEFAULT_URL_TEMPLATE
|
28
|
-
deserializer { |body| JSON.parse(body) }
|
29
|
-
|
30
|
-
handle([200, 201]) { |response| JSON.parse(response.body) }
|
31
|
-
|
32
|
-
handle(404) { raise Errors::NotFound }
|
33
|
-
handle(405) { raise Errors::MethodNotAllowed }
|
34
|
-
handle(422) { raise Errors::UnprocessableEntity }
|
35
|
-
handle(500) { raise Errors::InternalServerError }
|
36
|
-
|
37
|
-
field :id, type: String
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
28
|
end
|
42
29
|
|
43
|
-
# The default template used for generating resource urls.
|
44
|
-
DEFAULT_URL_TEMPLATE = '/{endpoint}{/id}{?query*}'
|
45
|
-
|
46
|
-
RESPONSE_HANDLERS = {}
|
47
|
-
|
48
30
|
module ClassMethods
|
49
31
|
|
50
|
-
def find(id)
|
51
|
-
body = make_request(:get, {}, id: id)
|
52
|
-
new(body)
|
53
|
-
end
|
54
|
-
|
55
32
|
def all(params={})
|
56
33
|
body = make_request(:get, {}, params)
|
57
|
-
self.
|
58
|
-
end
|
59
|
-
|
60
|
-
def has_many(name, options={})
|
61
|
-
self.associations ||= {}
|
62
|
-
self.associations[name] = {
|
63
|
-
association: Associations::HasManyAssociation,
|
64
|
-
options: options
|
65
|
-
}
|
66
|
-
end
|
67
|
-
|
68
|
-
def after_initialize(&block)
|
69
|
-
@after_initializers ||= []
|
70
|
-
@after_initializers << block
|
71
|
-
end
|
72
|
-
|
73
|
-
def handle(code, &block)
|
74
|
-
raise Arke::Errors::MissingHandlerBlock unless block_given?
|
75
|
-
case code
|
76
|
-
when String, Integer, Fixnum
|
77
|
-
response_handlers[code.to_i] = block
|
78
|
-
return true
|
79
|
-
when Range, Array
|
80
|
-
code.to_a.each do |c|
|
81
|
-
response_handlers[c.to_i] = block
|
82
|
-
end
|
83
|
-
return true
|
84
|
-
else
|
85
|
-
raise Errors::InvalidHandler.
|
86
|
-
new("#{code.class.name} is an invalid class, please user an Integer, Fixnum, String, Range or Array")
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def response_handlers
|
91
|
-
RESPONSE_HANDLERS
|
92
|
-
end
|
93
|
-
|
94
|
-
def collection(collection)
|
95
|
-
self._collection = collection if collection
|
34
|
+
self.collection.new(self, body)
|
96
35
|
end
|
97
36
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
# it will just return the URL template.
|
102
|
-
#
|
103
|
-
# @param [String] template the url template to set, if left nil, the method will simply return the current
|
104
|
-
# url template
|
105
|
-
#
|
106
|
-
# @return [Addressable::Template] the url template. If none has been set, it references {DEFAULT_URL_TEMPLATE}
|
107
|
-
def url_template(template)
|
108
|
-
self._url_template = Addressable::Template.new(template)
|
109
|
-
end
|
110
|
-
|
111
|
-
# Gets or sets the resource host.
|
112
|
-
#
|
113
|
-
# @param [String] host the resource host. if left nil, the method will simply return the current resource host
|
114
|
-
#
|
115
|
-
# @return [String] the current resource host
|
116
|
-
def host(host=nil)
|
117
|
-
@host = host if host
|
118
|
-
@host
|
119
|
-
end
|
120
|
-
|
121
|
-
# Gets the resource url. This compiles the url template using the passed options and returns the resulting
|
122
|
-
# string.
|
123
|
-
#
|
124
|
-
# @param [Hash] options the url options to pass to the template. By default the template looks for a an id and a
|
125
|
-
# query.
|
126
|
-
#
|
127
|
-
# @return [String] the full resource url
|
128
|
-
def url(options={})
|
129
|
-
template = options[:template] ? Addressable::Template.new(options.delete(:template)) : nil || _url_template
|
130
|
-
host + template.expand(options.merge(endpoint: endpoint)).to_s
|
131
|
-
end
|
132
|
-
|
133
|
-
# Gets or sets the device endpoint. By default the endpoint uses {#resource_name} if an endpoint has not been
|
134
|
-
# provided.
|
135
|
-
#
|
136
|
-
# @param [String] the service endpoint. if left nil it will simply return the existing endpoint
|
137
|
-
#
|
138
|
-
# @return [String] the service endpoint
|
139
|
-
def endpoint(endpoint=nil)
|
140
|
-
@endpoint = endpoint if endpoint
|
141
|
-
@endpoint ||= resource_name
|
142
|
-
end
|
143
|
-
|
144
|
-
def deserializer(&block)
|
145
|
-
self._deserializer = block if block_given?
|
146
|
-
end
|
147
|
-
|
148
|
-
def deserialize(body)
|
149
|
-
begin
|
150
|
-
self._deserializer.call(body)
|
151
|
-
rescue => e
|
152
|
-
raise Errors::DeserializationError.new(e)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def table_name
|
157
|
-
self.name.split('::')[-1].tableize
|
158
|
-
end
|
159
|
-
|
160
|
-
private
|
161
|
-
|
162
|
-
def resource_name
|
163
|
-
@resource_name ||= self.name.tableize
|
164
|
-
end
|
165
|
-
|
166
|
-
def make_request(method, body={}, params={})
|
167
|
-
begin
|
168
|
-
response = send(method, url(params), body)
|
169
|
-
rescue Errno::ECONNREFUSED
|
170
|
-
raise Errors::ConnectionRefused.new(host)
|
171
|
-
end
|
172
|
-
handle_response(response)
|
173
|
-
end
|
174
|
-
|
175
|
-
def handle_response(response)
|
176
|
-
response_handlers[response.code.to_i].call(response)
|
37
|
+
def find(id, params={})
|
38
|
+
body = make_request(:get, {}, {id: id}.merge(params))
|
39
|
+
new(body)
|
177
40
|
end
|
178
41
|
|
179
42
|
end
|
180
43
|
|
181
44
|
def initialize(attributes={})
|
182
45
|
@_attributes = attributes
|
183
|
-
self.class.after_initializers.each { |ai| ai.call } if self.class.after_initializers
|
184
46
|
end
|
185
47
|
|
186
48
|
def to_param
|
187
49
|
self.id
|
188
50
|
end
|
189
51
|
|
190
|
-
def persisted?
|
191
|
-
!self.id.empty?
|
192
|
-
end
|
193
|
-
|
194
|
-
def save
|
195
|
-
unless self.persisted?
|
196
|
-
return make_request(:post, @_attributes) && true
|
197
|
-
end
|
198
|
-
false
|
199
|
-
end
|
200
|
-
|
201
|
-
|
202
52
|
def inspect
|
203
53
|
id = "id: ''#{self.id}'" if try(:id)
|
204
54
|
"#<#{self.class.name}:0x%08x>" % (object_id * 2)
|
205
55
|
end
|
206
56
|
|
207
|
-
private
|
208
|
-
|
209
|
-
def make_request(method, body={}, params={})
|
210
|
-
begin
|
211
|
-
response = self.class.send(method, self.class.url(params.empty? ? body : params), {body: body})
|
212
|
-
rescue Errno::ECONNREFUSED
|
213
|
-
raise Errors::ConnectionRefused.new(host)
|
214
|
-
end
|
215
|
-
handle_response(response)
|
216
|
-
end
|
217
|
-
|
218
|
-
def handle_response(response)
|
219
|
-
self.class.response_handlers[response.code.to_i].call(response, self)
|
220
|
-
end
|
221
|
-
|
222
|
-
|
223
|
-
def method_missing(meth, *args)
|
224
|
-
return self.class.associations[meth.to_sym][:association].
|
225
|
-
new(self, meth.to_sym, self.class.associations[meth.to_sym][:options]) if self.class.associations && self.class.associations[meth.to_sym]
|
226
|
-
super
|
227
|
-
end
|
228
57
|
end
|
229
58
|
end
|
230
59
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Arke
|
2
|
+
module Resource
|
3
|
+
module Naming
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
delegate :singular_name, :resource_name, to: :class
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
def resource_name
|
13
|
+
self.name.tableize.split('/')[-1]
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def singular_name
|
18
|
+
resource_name.singularize
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Arke
|
2
|
+
module Resource
|
3
|
+
module Persistence
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module Callbacks
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
class_attribute :after_destroy_callbacks
|
11
|
+
|
12
|
+
alias_method_chain :destroy, :after_destroy
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
|
18
|
+
def after_destroy(method=nil, &block)
|
19
|
+
self.after_destroy_callbacks ||= []
|
20
|
+
self.after_destroy_callbacks << method if method
|
21
|
+
self.after_destroy_callbacks << block if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
included do
|
29
|
+
include Callbacks
|
30
|
+
include ActiveModel::Validations
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
module ClassMethods
|
35
|
+
|
36
|
+
def destroy(id)
|
37
|
+
new(id).destroy
|
38
|
+
end
|
39
|
+
|
40
|
+
def destroy_all(params={})
|
41
|
+
puts 'making delete request'
|
42
|
+
make_request(:delete, params)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def destroy
|
48
|
+
delete @_attributes
|
49
|
+
end
|
50
|
+
|
51
|
+
def save
|
52
|
+
unless self.persisted?
|
53
|
+
return true if (@_attributes = post(@_attributes))
|
54
|
+
else
|
55
|
+
return update(@_attributes)
|
56
|
+
end
|
57
|
+
false
|
58
|
+
end
|
59
|
+
|
60
|
+
def update(attributes)
|
61
|
+
@_attributes = attributes
|
62
|
+
return true if (@_attributes = put(@_attributes))
|
63
|
+
false
|
64
|
+
end
|
65
|
+
|
66
|
+
def reload
|
67
|
+
@_attributes = self.get(@_attributes.clone)
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
def persisted?
|
72
|
+
!self.id.empty?
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def destroy_with_after_destroy
|
78
|
+
destroy_without_after_destroy
|
79
|
+
self.after_destroy_callbacks ||= []
|
80
|
+
self.after_destroy_callbacks.each do |callback|
|
81
|
+
execute_callback(callback)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Arke
|
2
|
+
module Resource
|
3
|
+
module Requests
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
|
8
|
+
class_attribute :response_handlers
|
9
|
+
|
10
|
+
delegate :url, :post, :get, :delete, :put, :handle_response, to: :class
|
11
|
+
|
12
|
+
handle([200, 201, 204]) { |response| deserialize(response.body) }
|
13
|
+
|
14
|
+
handle(404) { raise Errors::NotFound }
|
15
|
+
handle(405) { raise Errors::MethodNotAllowed }
|
16
|
+
handle(422) { raise Errors::UnprocessableEntity }
|
17
|
+
handle(500) { raise Errors::InternalServerError }
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
|
23
|
+
def deserializer(&block)
|
24
|
+
@deserializer = block
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete(params={})
|
28
|
+
HTTParty.delete url(params)
|
29
|
+
end
|
30
|
+
|
31
|
+
def post(body={}, params={})
|
32
|
+
handle_response(HTTParty.post(url(params.empty? ? body : params), body: body))
|
33
|
+
end
|
34
|
+
|
35
|
+
def get(params={})
|
36
|
+
handle_response(HTTParty.get url(params))
|
37
|
+
end
|
38
|
+
|
39
|
+
def put(body={}, params={})
|
40
|
+
handle_response(HTTParty.put(url(params.empty? ? body : params), body: body))
|
41
|
+
end
|
42
|
+
|
43
|
+
def handle_response(response)
|
44
|
+
self.response_handlers[response.code.to_i].call(response)
|
45
|
+
end
|
46
|
+
|
47
|
+
def deserialize(body)
|
48
|
+
begin
|
49
|
+
@deserializer.call(body)
|
50
|
+
rescue => e
|
51
|
+
raise Errors::DeserializationError.new(e)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def handle(code, &block)
|
56
|
+
self.response_handlers ||= {}
|
57
|
+
raise Arke::Errors::MissingHandlerBlock unless block_given?
|
58
|
+
case code
|
59
|
+
when String, Integer, Fixnum
|
60
|
+
self.response_handlers[code.to_i] = block
|
61
|
+
return true
|
62
|
+
when Range, Array
|
63
|
+
code.to_a.each do |c|
|
64
|
+
self.response_handlers[c.to_i] = block
|
65
|
+
end
|
66
|
+
return true
|
67
|
+
else
|
68
|
+
raise Errors::InvalidHandler.
|
69
|
+
new("#{code.class.name} is an invalid class, please user an Integer, Fixnum, String, Range or Array")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Arke
|
2
|
+
module Resource
|
3
|
+
module URL
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
# The default template used for generating resource urls.
|
7
|
+
DEFAULT_URL_TEMPLATE = '/{endpoint}{/id}{?query*}'
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
# Gets or sets the url template for the resource. The url template is a
|
12
|
+
# {https://github.com/sporkmonger/addressable Addressable} template and defaults to {DEFAULT_URL_TEMPLATE}.
|
13
|
+
# If a parameter is passed to this method it will set the url template to the passed parameter, otherwise
|
14
|
+
# it will just return the URL template.
|
15
|
+
#
|
16
|
+
# @param [String] template the url template to set, if left nil, the method will simply return the current
|
17
|
+
# url template
|
18
|
+
#
|
19
|
+
# @return [Addressable::Template] the url template. If none has been set, it references {DEFAULT_URL_TEMPLATE}
|
20
|
+
def url_template(template=nil)
|
21
|
+
@url_template = Addressable::Template.new(template) if template
|
22
|
+
@url_template || Addressable::Template.new(DEFAULT_URL_TEMPLATE)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Gets or sets the resource host.
|
26
|
+
#
|
27
|
+
# @param [String] host the resource host. if left nil, the method will simply return the current resource host
|
28
|
+
#
|
29
|
+
# @return [String] the current resource host
|
30
|
+
def host(host=nil)
|
31
|
+
@host = host if host
|
32
|
+
@host
|
33
|
+
end
|
34
|
+
|
35
|
+
# Gets the resource url. This compiles the url template using the passed options and returns the resulting
|
36
|
+
# string.
|
37
|
+
#
|
38
|
+
# @param [Hash] options the url options to pass to the template. By default the template looks for a an id and a
|
39
|
+
# query.
|
40
|
+
#
|
41
|
+
# @return [String] the full resource url
|
42
|
+
def url(options={})
|
43
|
+
template = options[:_template] ? Addressable::Template.new(options.delete(:_template)) : nil ||self.url_template
|
44
|
+
association_options = {parent_resource_name: options.delete(:_parent_resource_name), relation_id: options.delete(:_relation_id), resource_name: options.delete(:_resource_name)}
|
45
|
+
host + template.expand(association_options.merge(options.merge(endpoint: endpoint))).to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
# Gets or sets the device endpoint. By default the endpoint uses {#resource_name} if an endpoint has not been
|
49
|
+
# provided.
|
50
|
+
#
|
51
|
+
# @param [String] the service endpoint. if left nil it will simply return the existing endpoint
|
52
|
+
#
|
53
|
+
# @return [String] the service endpoint
|
54
|
+
def endpoint(endpoint=nil)
|
55
|
+
@endpoint = endpoint if endpoint
|
56
|
+
@endpoint ||= resource_name
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/arke/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Arke
|
2
|
-
VERSION = '0.0
|
3
|
-
end
|
2
|
+
VERSION = '0.1.0'
|
3
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jarod Reid
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05
|
11
|
+
date: 2014-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -156,12 +156,17 @@ files:
|
|
156
156
|
- lib/arke/mime_types.rb
|
157
157
|
- lib/arke/resource.rb
|
158
158
|
- lib/arke/resource/associations.rb
|
159
|
-
- lib/arke/resource/
|
160
|
-
- lib/arke/resource/associations/has_many_association.rb
|
159
|
+
- lib/arke/resource/callbacks.rb
|
161
160
|
- lib/arke/resource/collection.rb
|
161
|
+
- lib/arke/resource/collections.rb
|
162
162
|
- lib/arke/resource/errors.rb
|
163
163
|
- lib/arke/resource/fields.rb
|
164
|
+
- lib/arke/resource/finders.rb
|
164
165
|
- lib/arke/resource/model.rb
|
166
|
+
- lib/arke/resource/naming.rb
|
167
|
+
- lib/arke/resource/persistence.rb
|
168
|
+
- lib/arke/resource/requests.rb
|
169
|
+
- lib/arke/resource/url.rb
|
165
170
|
- lib/arke/version.rb
|
166
171
|
- spec/resource_spec.rb
|
167
172
|
homepage: ''
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Arke
|
2
|
-
module Resource
|
3
|
-
module Associations
|
4
|
-
class Base
|
5
|
-
|
6
|
-
attr_reader :name, :options
|
7
|
-
|
8
|
-
def initialize(parent, name, options={})
|
9
|
-
@parent = parent
|
10
|
-
@name = name
|
11
|
-
@options = options
|
12
|
-
end
|
13
|
-
|
14
|
-
def target
|
15
|
-
klass.constantize
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def klass
|
21
|
-
"#{@parent.class.name.split('::')[0..-2].join('::')}::#{@options[:class_name] || name.to_s.classify}"
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Arke
|
2
|
-
module Resource
|
3
|
-
module Associations
|
4
|
-
|
5
|
-
class HasManyAssociation < Base
|
6
|
-
include Enumerable
|
7
|
-
delegate :find, to: :target
|
8
|
-
|
9
|
-
def all(params={})
|
10
|
-
target.all(params.merge({
|
11
|
-
template: "/#{@parent.class.table_name}/#{@parent.send(options[:foreign_key] || :id)}/{endpoint}"
|
12
|
-
}))
|
13
|
-
end
|
14
|
-
|
15
|
-
def each(&block)
|
16
|
-
self.all.each &block
|
17
|
-
end
|
18
|
-
|
19
|
-
def count(params={})
|
20
|
-
all(params).count
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|