arrest 0.0.21 → 0.0.23

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.
@@ -6,6 +6,45 @@ require 'active_model'
6
6
  Scope = Struct.new(:name, :block)
7
7
 
8
8
  module Arrest
9
+
10
+ class RequestContext
11
+ attr_accessor :header_decorator
12
+ end
13
+
14
+ class ScopedRoot
15
+ attr_accessor :context
16
+
17
+ def initialize(context = Arrest::RequestContext.new())
18
+ @context = context
19
+ end
20
+
21
+ def self.register_resource(clazz)
22
+ send :define_method, ClassUtils.simple_name(clazz) do ||
23
+ proxy = clazz.mk_proxy(self)
24
+ proxy
25
+ end
26
+ end
27
+
28
+ def get_context
29
+ @context
30
+ end
31
+ end
32
+
33
+ class ResourceProxy
34
+ def initialize(resource, context_provider)
35
+ @resource = resource
36
+ @context_provider = context_provider
37
+ end
38
+
39
+
40
+ def method_missing(*args, &block)
41
+ params = [@context_provider.get_context]
42
+ params += args.drop(1)
43
+ @resource.send(args.first, *params)
44
+ end
45
+
46
+ end
47
+
9
48
  class AbstractResource
10
49
  extend ActiveModel::Naming
11
50
  include ActiveModel::Validations
@@ -13,9 +52,19 @@ module Arrest
13
52
  include HasAttributes
14
53
  attribute :id, String
15
54
 
55
+ attr_accessor :context
56
+
16
57
  class << self
17
58
  attr_reader :scopes
18
59
 
60
+ def inherited(child)
61
+ ScopedRoot::register_resource(child)
62
+ end
63
+
64
+ def mk_proxy(context_provider)
65
+ ResourceProxy.new(self, context_provider)
66
+ end
67
+
19
68
  def source
20
69
  Arrest::Source::source
21
70
  end
@@ -33,8 +82,7 @@ module Arrest
33
82
  end
34
83
 
35
84
  def build(hash)
36
- resource = self.new(hash, true)
37
-
85
+ resource = self.new(@context, hash, true)
38
86
  resource
39
87
  end
40
88
 
@@ -46,7 +94,7 @@ module Arrest
46
94
  if @custom_resource_name
47
95
  @custom_resource_name
48
96
  else
49
- StringUtils.plural self.name.sub(/.*:/,'').downcase
97
+ StringUtils.plural(self.name.sub(/.*:/,'').downcase)
50
98
  end
51
99
  end
52
100
 
@@ -148,7 +196,8 @@ module Arrest
148
196
 
149
197
  attr_accessor :id
150
198
 
151
- def initialize(hash={}, from_json = false)
199
+ def initialize(context, hash={}, from_json = false)
200
+ @context = context
152
201
  initialize_has_attributes(hash, from_json)
153
202
  end
154
203
 
@@ -156,14 +205,14 @@ module Arrest
156
205
  if Source.skip_validations || self.valid?
157
206
  req_type = new_record? ? :post : :put
158
207
 
159
- success = !!AbstractResource::source.send(req_type, self)
208
+ success = !!AbstractResource::source.send(req_type, @context, self)
160
209
 
161
210
  if success
162
211
  # check for sub resources in case of n:m relationships
163
212
  self.class.all_fields.find_all{|f| f.is_a?(HasManySubResourceAttribute)}.each do |attr|
164
213
  ids = self.send(attr.name) # get ids_field e.g. for team has_many :users get 'self.user_ids'
165
214
  srifn = attr.sub_resource_field_name
166
- result = !!AbstractResource::source.put_sub_resource(self, srifn, ids)
215
+ result = !!AbstractResource::source.put_sub_resource( self, srifn, ids)
167
216
  return false if !result
168
217
  end
169
218
  return true
@@ -177,7 +226,7 @@ module Arrest
177
226
  end
178
227
 
179
228
  def delete
180
- AbstractResource::source().delete self
229
+ AbstractResource::source().delete(@context, self)
181
230
  true
182
231
  end
183
232
 
@@ -8,7 +8,7 @@ module Arrest
8
8
  @json_name = Source.json_key_converter.key_to_json(name).to_sym
9
9
  end
10
10
 
11
- def from_hash value
11
+ def from_hash(parent, value)
12
12
  return if value == nil
13
13
  converter = CONVERTER[@clazz]
14
14
  if converter == nil
@@ -28,4 +28,4 @@ module Arrest
28
28
  converter.mk_json value
29
29
  end
30
30
  end
31
- end
31
+ end
@@ -51,9 +51,9 @@ module Arrest
51
51
 
52
52
  begin
53
53
  if polymorphic
54
- Arrest::Source.mod.const_get(polymorphic[val.type.to_sym]).find(val.id)
54
+ Arrest::Source.mod.const_get(polymorphic[val.type.to_sym]).find(self.context, val.id)
55
55
  else
56
- Arrest::Source.mod.const_get(class_name).find(val)
56
+ Arrest::Source.mod.const_get(class_name).find(self.context, val)
57
57
  end
58
58
  rescue Errors::DocumentNotFoundError => e
59
59
  raise Errors::DocumentNotFoundError, "Couldnt find a #{class_name} with id #{val}"
@@ -9,11 +9,11 @@ module Arrest
9
9
  super name, read_only, clazz
10
10
  end
11
11
 
12
- def from_hash value
12
+ def from_hash(parent, value)
13
13
  return nil unless value != nil
14
14
  raise "Expected an array but got #{value.class.name}" unless value.is_a?(Array)
15
15
  value.map do |v|
16
- @clazz.new v
16
+ @clazz.new(parent, v)
17
17
  end
18
18
  end
19
19
 
@@ -10,10 +10,12 @@ module Arrest
10
10
  else
11
11
  @stubbed = false
12
12
  end
13
+ raise "hash expected but got #{hash.class}" unless hash.is_a?(Hash)
13
14
  init_from_hash(hash, from_json)
14
15
  end
15
16
 
16
17
  def initialize(hash = {}, from_json = false, &blk)
18
+ raise "hash expected but got #{hash.class}" unless hash.is_a?(Hash)
17
19
  if block_given?
18
20
  @stubbed = true
19
21
  @load_blk = blk
@@ -27,6 +29,7 @@ module Arrest
27
29
  end
28
30
 
29
31
  def init_from_hash(as_i={}, from_json = false)
32
+ raise "hash expected but got #{as_i.class}" unless as_i.is_a?(Hash)
30
33
  @attribute_values = {} unless @attribute_values != nil
31
34
  as = {}
32
35
  as_i.each_pair do |k,v|
@@ -39,7 +42,7 @@ module Arrest
39
42
  key = field.name
40
43
  end
41
44
  value = as[key]
42
- converted = field.from_hash(value)
45
+ converted = field.from_hash(self, value)
43
46
  self.send(field.name.to_s + '=', converted) unless converted == nil
44
47
  end
45
48
  end
@@ -51,7 +54,7 @@ module Arrest
51
54
  matching_fields = fields.find_all{|f| f.name.to_s == k.to_s}
52
55
  field = matching_fields.first
53
56
  if field
54
- converted = field.from_hash(v)
57
+ converted = field.from_hash(self, v)
55
58
  self.send("#{k}=", converted)
56
59
  end
57
60
  end
@@ -16,9 +16,9 @@ module Arrest
16
16
  @name
17
17
  end
18
18
 
19
- def from_hash(value)
19
+ def from_hash(parent, value)
20
20
  return [] if value == nil
21
- super_from_hash(value)
21
+ super_from_hash(parent, value)
22
22
  end
23
23
  end
24
24
  end
@@ -4,9 +4,9 @@ module Arrest
4
4
  super name, read_only, clazz
5
5
  end
6
6
 
7
- def from_hash value
7
+ def from_hash(parent, value)
8
8
  return nil unless value != nil
9
- @clazz.new value
9
+ @clazz.new(parent, value)
10
10
  end
11
11
 
12
12
  def to_hash val
@@ -14,4 +14,4 @@ module Arrest
14
14
  val.to_hash
15
15
  end
16
16
  end
17
- end
17
+ end
@@ -10,5 +10,10 @@ module Arrest
10
10
  def initialize name, read_only
11
11
  super name, read_only, Ref
12
12
  end
13
+
14
+ def from_hash(parent, value)
15
+ return nil unless value != nil
16
+ @clazz.new(value)
17
+ end
13
18
  end
14
- end
19
+ end
@@ -12,7 +12,7 @@ module Arrest
12
12
 
13
13
  def build attributes = {}
14
14
  extended_attrs = attributes.merge({@foreign_key_name => @parent.id})
15
- resolved_class.new extended_attrs
15
+ resolved_class.new(@parent.context, extended_attrs)
16
16
  end
17
17
 
18
18
  def method_missing(*args, &block)
@@ -28,7 +28,7 @@ module Arrest
28
28
  def children
29
29
  if @children == nil
30
30
  url = @parent.resource_location + '/' + @url_part.to_s
31
- @children = resolved_class.by_url(url)
31
+ @children = resolved_class.by_url(@parent.context, url)
32
32
  end
33
33
  @children
34
34
  end
@@ -13,16 +13,18 @@ module Arrest
13
13
  @base
14
14
  end
15
15
 
16
- def add_headers(headers)
17
- Arrest::Source.header_decorator.headers.each_pair do |k,v|
16
+ def add_headers(context,headers)
17
+ decorator = context.header_decorator if context
18
+ decorator ||= Arrest::Source.header_decorator
19
+ decorator.headers.each_pair do |k,v|
18
20
  headers[k.to_s] = v.to_s
19
21
  end
20
22
  end
21
23
 
22
- def get_one(sub, filter={})
24
+ def get_one(context, sub, filter={})
23
25
  response = self.connection().get do |req|
24
26
  req.url(sub, filter)
25
- add_headers(req.headers)
27
+ add_headers(context, req.headers)
26
28
  end
27
29
  rql = RequestLog.new(:get, "#{sub}#{hash_to_query filter}", nil)
28
30
  rsl = ResponseLog.new(response.env[:status], response.body)
@@ -33,14 +35,14 @@ module Arrest
33
35
  response.body
34
36
  end
35
37
 
36
- def get_many_other_ids(path)
37
- get_one(path)
38
+ def get_many_other_ids(context, path)
39
+ get_one(context, path)
38
40
  end
39
41
 
40
- def get_many(sub, filter={})
42
+ def get_many(context, sub, filter={})
41
43
  response = self.connection().get do |req|
42
44
  req.url(sub, filter)
43
- add_headers(req.headers)
45
+ add_headers(context, req.headers)
44
46
  end
45
47
  rql = RequestLog.new(:get, "#{sub}#{hash_to_query filter}", nil)
46
48
  rsl = ResponseLog.new(response.env[:status], response.body)
@@ -49,10 +51,10 @@ module Arrest
49
51
  end
50
52
 
51
53
 
52
- def delete_all(resource_path)
54
+ def delete_all(context, resource_path)
53
55
  response = self.connection().delete do |req|
54
56
  req.url(resource_path)
55
- add_headers(req.headers)
57
+ add_headers(context, req.headers)
56
58
  end
57
59
  rql = RequestLog.new(:delete, "#{resource_path}", nil)
58
60
  rsl = ResponseLog.new(response.env[:status], response.body)
@@ -61,11 +63,11 @@ module Arrest
61
63
  response.env[:status] == 200
62
64
  end
63
65
 
64
- def delete(rest_resource)
66
+ def delete(context, rest_resource)
65
67
  raise "To delete an object it must have an id" unless rest_resource.respond_to?(:id) && rest_resource.id != nil
66
68
  response = self.connection().delete do |req|
67
69
  req.url(rest_resource.resource_location)
68
- add_headers(req.headers)
70
+ add_headers(context, req.headers)
69
71
  end
70
72
  rql = RequestLog.new(:delete, rest_resource.resource_location, nil)
71
73
  rsl = ResponseLog.new(response.env[:status], response.body)
@@ -80,7 +82,7 @@ module Arrest
80
82
  internal_put(rest_resource, location, body)
81
83
  end
82
84
 
83
- def put(rest_resource)
85
+ def put(context, rest_resource)
84
86
  raise "To change an object it must have an id" unless rest_resource.respond_to?(:id) && rest_resource.id != nil
85
87
  hash = rest_resource.to_jhash
86
88
  hash.delete(:id)
@@ -90,10 +92,13 @@ module Arrest
90
92
  internal_put(rest_resource, rest_resource.resource_location, body)
91
93
  end
92
94
 
95
+
96
+
97
+
93
98
  def internal_put(rest_resource, location, body)
94
99
  response = self.connection().put do |req|
95
100
  req.url(location)
96
- add_headers(req.headers)
101
+ add_headers(rest_resource.context, req.headers)
97
102
  req.body = body
98
103
  end
99
104
  rql = RequestLog.new(:put, location, body)
@@ -105,7 +110,7 @@ module Arrest
105
110
  response.env[:status] == 200
106
111
  end
107
112
 
108
- def post(rest_resource)
113
+ def post(context, rest_resource)
109
114
  raise "new object must have setter for id" unless rest_resource.respond_to?(:id=)
110
115
  raise "new object must not have id" if rest_resource.respond_to?(:id) && rest_resource.id != nil
111
116
  hash = rest_resource.to_jhash
@@ -117,7 +122,7 @@ module Arrest
117
122
  body = hash.to_json
118
123
  response = self.connection().post do |req|
119
124
  req.url rest_resource.resource_path
120
- add_headers req.headers
125
+ add_headers(context, req.headers)
121
126
  req.body = body
122
127
  end
123
128
  rql = RequestLog.new(:post, rest_resource.resource_path, body)
@@ -97,7 +97,7 @@ module Arrest
97
97
  []
98
98
  end
99
99
 
100
- def get_many_other_ids(path)
100
+ def get_many_other_ids(context,path)
101
101
  matcher = /^.+\/([^\/]+)\/([^\/]+)_ids$/.match(path)
102
102
  return [] unless matcher
103
103
  object_id = matcher[1]
@@ -114,7 +114,7 @@ module Arrest
114
114
  wrap id_list, id_list.length
115
115
  end
116
116
 
117
- def get_many(sub, filters = {})
117
+ def get_many(context,sub, filters = {})
118
118
  Arrest::debug sub + (hash_to_query filters)
119
119
  # filters are ignored by mem impl so far
120
120
 
@@ -130,7 +130,7 @@ module Arrest
130
130
  wrap collection_json(objects), id_list.length
131
131
  end
132
132
 
133
- def get_one sub, filters = {}
133
+ def get_one(context, sub, filters = {})
134
134
  Arrest::debug sub + (hash_to_query filters)
135
135
  # filters are ignored by mem impl so far
136
136
  idx = sub.rindex '/'
@@ -144,7 +144,7 @@ module Arrest
144
144
  wrap val.to_jhash.to_json, 1
145
145
  end
146
146
 
147
- def delete_all resource_path
147
+ def delete_all(context, resource_path)
148
148
  id_list = Array.new(@@collections[resource_path] || [])
149
149
  id_list.each do |base_id|
150
150
  @@collections.each_pair do |k,v|
@@ -175,7 +175,7 @@ module Arrest
175
175
  end
176
176
 
177
177
 
178
- def delete(rest_resource)
178
+ def delete(context, rest_resource)
179
179
  raise "To change an object it must have an id" unless rest_resource.respond_to?(:id) && rest_resource.id != nil
180
180
  @@all_objects.delete(rest_resource.id)
181
181
  @@collections.each_pair do |k,v|
@@ -281,7 +281,7 @@ module Arrest
281
281
  true
282
282
  end
283
283
 
284
- def put(rest_resource)
284
+ def put(context, rest_resource)
285
285
  raise "To change an object it must have an id" unless rest_resource.respond_to?(:id) && rest_resource.id != nil
286
286
  old = @@all_objects[rest_resource.id]
287
287
 
@@ -298,7 +298,7 @@ module Arrest
298
298
 
299
299
 
300
300
 
301
- def post(rest_resource)
301
+ def post(context, rest_resource)
302
302
 
303
303
  Arrest::debug "post -> #{rest_resource.class.name} #{rest_resource.to_hash} #{rest_resource.class.all_fields.map(&:name)}"
304
304
  raise "new object must have setter for id" unless rest_resource.respond_to?(:id=)
@@ -6,8 +6,15 @@ module Arrest
6
6
  include HasAttributes
7
7
  include BelongsTo
8
8
 
9
- def initialize h
9
+ attr_reader :parent
10
+
11
+ def initialize parent, h
12
+ @parent = parent
10
13
  init_from_hash h
11
14
  end
15
+
16
+ def context
17
+ parent.context
18
+ end
12
19
  end
13
20
  end
@@ -1,8 +1,8 @@
1
1
  module Arrest
2
2
  class RestChild < AbstractResource
3
3
  attr_accessor :parent
4
- def initialize parent, h
5
- super h
4
+ def initialize context, parent, h
5
+ super(context,h)
6
6
  @parent = parent
7
7
  end
8
8
 
@@ -17,14 +17,14 @@ module Arrest
17
17
  end
18
18
 
19
19
  def build parent, hash
20
- self.new parent, hash
20
+ self.new(parent.context, parent, hash)
21
21
  end
22
22
 
23
23
 
24
- def all_for parent
24
+ def all_for(parent)
25
25
  raise "Parent has no id yet" unless parent.id
26
26
  begin
27
- body_root(source().get_many self.resource_path_for(parent)).map do |h|
27
+ body_root(source().get_many(parent.context, self.resource_path_for(parent))).map do |h|
28
28
  self.build(parent, h)
29
29
  end
30
30
  rescue Arrest::Errors::DocumentNotFoundError
@@ -32,14 +32,14 @@ module Arrest
32
32
  end
33
33
  end
34
34
 
35
- def find id
35
+ def find(context, id)
36
36
  raise "find cannot be executed for child resources - use find_for with a parent"
37
37
  end
38
38
 
39
- def find_for parent,id
40
- r = source().get_one "#{self.resource_path_for(parent)}/#{id}"
39
+ def find_for(context, parent,id)
40
+ r = source().get_one(context, "#{self.resource_path_for(parent)}/#{id}")
41
41
  body = body_root(r)
42
- self.build body
42
+ self.build(body)
43
43
  end
44
44
 
45
45
  def filter name, &aproc
@@ -54,7 +54,7 @@ module Arrest
54
54
  end
55
55
  end
56
56
 
57
- def scope name, &block
57
+ def scope(name, &block)
58
58
  super name
59
59
  if block_given?
60
60
  send :define_singleton_method, name do |parent|
@@ -63,7 +63,7 @@ module Arrest
63
63
  else
64
64
  send :define_singleton_method, name do |parent|
65
65
  raise "Parent has no id yet" unless parent.id
66
- body_root(source().get_many self.scoped_path_for(parent, name)).map do |h|
66
+ body_root(source().get_many(parent.context, self.scoped_path_for(parent, name))).map do |h|
67
67
  self.build(parent, h)
68
68
  end
69
69
  end