Class: Aptible::Resource::Base
Overview
rubocop:disable ClassLength rubocop:disable DuplicateMethods
Constant Summary
HyperResource::VERSION, HyperResource::VERSION_DATE
HyperResource::Modules::HTTP::CONTENT_TYPE_HEADERS, HyperResource::Modules::HTTP::MAX_COORDINATOR_RETRIES
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#[], _hr_deprecate, #_hr_new_from_link, #_hr_response_class, #changed?, #deserialized_response, #each, #get_data_type_from_response, #incoming_body_filter, #inspect, #method_missing, namespaced_class, #outgoing_body_filter, #outgoing_uri_filter, #response_body, response_class, #response_object
included
#configure_client, #create, #get, initialize_http_client!, #patch, #post, #put
Constructor Details
#initialize(options = {}) ⇒ Base
rubocop:disable ReturnInVoidContext
233
234
235
236
237
238
239
|
# File 'lib/aptible/resource/base.rb', line 233
def initialize(options = {})
return super(options) unless options.is_a?(Hash)
populate_default_options!(options)
super(options)
self.token = options[:token] if options[:token]
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
in the class HyperResource
Instance Attribute Details
#errors ⇒ Object
Returns the value of attribute errors.
21
22
23
|
# File 'lib/aptible/resource/base.rb', line 21
def errors
@errors
end
|
#token ⇒ Object
Returns the value of attribute token.
22
23
24
|
# File 'lib/aptible/resource/base.rb', line 22
def token
@token
end
|
Class Method Details
.adapter ⇒ Object
30
31
32
|
# File 'lib/aptible/resource/base.rb', line 30
def self.adapter
Aptible::Resource::Adapter
end
|
.all(options = {}) ⇒ Object
61
62
63
64
65
|
# File 'lib/aptible/resource/base.rb', line 61
def self.all(options = {})
out = []
each_page(options) { |page| out.concat page }
out
end
|
.basename ⇒ Object
38
39
40
|
# File 'lib/aptible/resource/base.rb', line 38
def self.basename
name.split('::').last.underscore.pluralize
end
|
.belongs_to(relation) ⇒ Object
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/aptible/resource/base.rb', line 122
def self.belongs_to(relation)
define_method relation do
get unless loaded
if (memoized = instance_variable_get("@#{relation}"))
memoized
elsif links[relation]
instance_variable_set("@#{relation}", links[relation].get)
end
end
end
|
.cast_field(value, type) ⇒ Object
222
223
224
225
226
227
228
229
230
|
# File 'lib/aptible/resource/base.rb', line 222
def self.cast_field(value, type)
if type == Time
Time.parse(value) if value
elsif type == DateTime
DateTime.parse(value) if value
else
value
end
end
|
.collection_href ⇒ Object
34
35
36
|
# File 'lib/aptible/resource/base.rb', line 34
def self.collection_href
"/#{basename}"
end
|
.create(params = {}) ⇒ Object
95
96
97
98
99
|
# File 'lib/aptible/resource/base.rb', line 95
def self.create(params = {})
create!(params)
rescue HyperResource::ResponseError => e
new.tap { |resource| resource.errors = Errors.from_exception(e) }
end
|
.create!(params = {}) ⇒ Object
89
90
91
92
93
|
# File 'lib/aptible/resource/base.rb', line 89
def self.create!(params = {})
token = params.delete(:token)
resource = new(token: token)
resource.send(basename).create(normalize_params(params))
end
|
.define_embeds_many_getters(relation) ⇒ Object
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
# File 'lib/aptible/resource/base.rb', line 179
def self.define_embeds_many_getters(relation)
define_method relation do
get unless loaded
objects[relation].entries
end
iterator_method = "each_#{relation.to_s.singularize}".to_sym
define_method iterator_method do |&block|
next enum_for(iterator_method) if block.nil?
send(relation).each(&block)
end
end
|
.define_has_many_getters(relation) ⇒ Object
rubocop:disable MethodLength rubocop:disable AbcSize
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
# File 'lib/aptible/resource/base.rb', line 142
def self.define_has_many_getters(relation)
define_method relation do
get unless loaded
if (memoized = instance_variable_get("@#{relation}"))
memoized
elsif links[relation]
depaginated = self.class.all(href: links[relation].base_href,
token: token,
headers: )
instance_variable_set("@#{relation}", depaginated)
end
end
iterator_method = "each_#{relation.to_s.singularize}".to_sym
define_method iterator_method do |&block|
next enum_for(iterator_method) if block.nil?
self.class.each_page(
href: links[relation].base_href,
token: token,
headers:
) do |page|
page.each { |entry| block.call entry }
end
end
end
|
.define_has_many_setter(relation) ⇒ Object
rubocop:disable MethodLength rubocop:disable AbcSize
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
# File 'lib/aptible/resource/base.rb', line 196
def self.define_has_many_setter(relation)
define_method "create_#{relation.to_s.singularize}!" do |params = {}|
get unless loaded
links[relation].create(self.class.normalize_params(params))
end
define_method "create_#{relation.to_s.singularize}" do |params = {}|
begin
send "create_#{relation.to_s.singularize}!", params
rescue HyperResource::ResponseError => e
Base.new(root: root_url, namespace: namespace).tap do |base|
base.errors = Errors.from_exception(e)
end
end
end
end
|
.each_page(options = {}) ⇒ Object
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
# File 'lib/aptible/resource/base.rb', line 42
def self.each_page(options = {})
return enum_for(:each_page, options) unless block_given?
href = options[:href] || collection_href
while href
resource = find_by_url(href, options)
break if resource.nil?
yield resource.entries
next_link = resource.links['next']
href = next_link ? next_link.href : nil
end
end
|
.embeds_many(relation) ⇒ Object
rubocop:enable PredicateName
108
109
110
111
|
# File 'lib/aptible/resource/base.rb', line 108
def self.embeds_many(relation)
define_embeds_many_getters(relation)
define_has_many_setter(relation)
end
|
.embeds_one(relation) ⇒ Object
rubocop:enable AbcSize rubocop:enable MethodLength
172
173
174
175
176
177
|
# File 'lib/aptible/resource/base.rb', line 172
def self.embeds_one(relation)
define_method relation do
get unless loaded
objects[relation]
end
end
|
.field(name, options = {}) ⇒ Object
113
114
115
116
117
118
119
120
|
# File 'lib/aptible/resource/base.rb', line 113
def self.field(name, options = {})
define_method name do
self.class.cast_field(attributes[name], options[:type])
end
define_method("#{name}?") { !!send(name) } if options[:type] == Boolean
end
|
.find(id, options = {}) ⇒ Object
73
74
75
76
77
78
|
# File 'lib/aptible/resource/base.rb', line 73
def self.find(id, options = {})
params = options.except(:token, :root, :namespace, :headers)
params = normalize_params(params)
params = params.empty? ? '' : '?' + params.to_query
find_by_url("#{collection_href}/#{id}#{params}", options)
end
|
.find_by_url(url, options = {}) ⇒ Object
80
81
82
83
84
85
86
87
|
# File 'lib/aptible/resource/base.rb', line 80
def self.find_by_url(url, options = {})
new(options).find_by_url(url)
rescue HyperResource::ClientError => e
return nil if e.response.status == 404
raise e
end
|
.get_data_type_from_response(response) ⇒ Object
24
25
26
27
28
|
# File 'lib/aptible/resource/base.rb', line 24
def self.get_data_type_from_response(response)
return nil unless response && response.body
adapter.get_data_type_from_object(adapter.deserialize(response.body))
end
|
.has_many(relation) ⇒ Object
rubocop:disable PredicateName
102
103
104
105
|
# File 'lib/aptible/resource/base.rb', line 102
def self.has_many(relation)
define_has_many_getters(relation)
define_has_many_setter(relation)
end
|
.has_one(relation) ⇒ Object
rubocop:disable PredicateName
134
135
136
137
|
# File 'lib/aptible/resource/base.rb', line 134
def self.has_one(relation)
belongs_to(relation)
end
|
.normalize_params(params = {}) ⇒ Object
rubocop: enable AbcSize rubocop:enable MethodLength
215
216
217
218
219
220
|
# File 'lib/aptible/resource/base.rb', line 215
def self.normalize_params(params = {})
params_array = params.map do |key, value|
value.is_a?(HyperResource) ? [key, value.href] : [key, value]
end
Hash[params_array]
end
|
.where(options = {}) ⇒ Object
67
68
69
70
71
|
# File 'lib/aptible/resource/base.rb', line 67
def self.where(options = {})
params = options.except(:token, :root, :namespace, :headers)
params = normalize_params(params)
find_by_url("#{collection_href}?#{params.to_query}", options).entries
end
|
Instance Method Details
#_hyperresource_update ⇒ Object
rubocop:disable Style/Alias
281
|
# File 'lib/aptible/resource/base.rb', line 281
alias_method :_hyperresource_update, :update
|
#adapter ⇒ Object
254
255
256
|
# File 'lib/aptible/resource/base.rb', line 254
def adapter
self.class.adapter
end
|
#bearer_token ⇒ Object
272
273
274
275
276
277
278
|
# File 'lib/aptible/resource/base.rb', line 272
def bearer_token
case token
when Aptible::Resource::Base then token.access_token
when Fridge::AccessToken then token.to_s
when String then token
end
end
|
#delete ⇒ Object
Also known as:
destroy
297
298
299
300
301
302
303
304
305
306
307
|
# File 'lib/aptible/resource/base.rb', line 297
def delete
super
rescue HyperResource::ServerError
raise
rescue HyperResource::ClientError => e
raise unless e.response.status == 404
rescue HyperResource::ResponseError
nil
end
|
#error_html ⇒ Object
322
323
324
|
# File 'lib/aptible/resource/base.rb', line 322
def error_html
errors.full_messages.join('<br />')
end
|
#find_by_url(url_or_href) ⇒ Object
266
267
268
269
270
|
# File 'lib/aptible/resource/base.rb', line 266
def find_by_url(url_or_href)
resource = dup
resource.href = url_or_href.gsub(/^#{root}/, '')
resource.get
end
|
#namespace ⇒ Object
258
259
260
|
# File 'lib/aptible/resource/base.rb', line 258
def namespace
raise 'Resource server namespace must be defined by subclass'
end
|
#populate_default_options!(options) ⇒ Object
rubocop:enable ReturnInVoidContext
242
243
244
245
246
247
|
# File 'lib/aptible/resource/base.rb', line 242
def populate_default_options!(options)
options[:root] ||= root_url
options[:namespace] ||= namespace
options[:headers] ||= {}
options[:headers]['Content-Type'] = 'application/json'
end
|
#reload ⇒ Object
NOTE: The following does not update the object in-place
314
315
316
|
# File 'lib/aptible/resource/base.rb', line 314
def reload
self.class.find_by_url(href, token: token, headers: )
end
|
#root_url ⇒ Object
262
263
264
|
# File 'lib/aptible/resource/base.rb', line 262
def root_url
raise 'Resource server root URL must be defined by subclass'
end
|
#update(params) ⇒ Object
291
292
293
294
295
|
# File 'lib/aptible/resource/base.rb', line 291
def update(params)
update!(params)
rescue HyperResource::ResponseError
false
end
|
#update!(params) ⇒ Object
rubocop:enable Style/Alias
284
285
286
287
288
289
|
# File 'lib/aptible/resource/base.rb', line 284
def update!(params)
_hyperresource_update(self.class.normalize_params(params))
rescue HyperResource::ResponseError => e
self.errors = Errors.from_exception(e)
raise e
end
|