Class: Latitude::API::APIResource
Direct Known Subclasses
Resources::APIKey, Resources::ElasticIP, Resources::Event, Resources::Firewall, Resources::Firewall::Assignment, Resources::IP, Resources::KubernetesCluster, Resources::Plan, Resources::Plan::Bandwidth, Resources::Plan::OperatingSystem, Resources::Plan::Storage, Resources::Plan::VirtualMachine, Resources::Project, Resources::Project::SSHKey, Resources::Project::UserData, Resources::Region, Resources::Role, Resources::SSHKey, Resources::Server, Resources::Storage::Filesystem, Resources::Storage::Object, Resources::Storage::Volume, Resources::Tag, Resources::Team, Resources::Team::Member, Resources::UserData, Resources::UserTeam, Resources::VPNSession, Resources::VirtualMachine, Resources::VirtualNetwork, Resources::VirtualNetwork::Assignment, SingletonAPIResource
Constant Summary
collapse
- READ_ONLY_ATTRIBUTES =
%w[id type created_at updated_at].freeze
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
attribute, attribute_specs
#attribute_spec, #read_attribute, #wrap_attribute
Constructor Details
#initialize(data, meta: nil, path_params: {}, opts: {}) ⇒ APIResource
Returns a new instance of APIResource.
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/latitude/api/api_resource.rb', line 107
def initialize(data, meta: nil, path_params: {}, opts: {})
@raw_data = data
@id = data["id"]
@type = data["type"]
@meta = data["meta"] || meta || {}
@path_params = path_params || {}
@opts = opts || {}
@values = {}
@unsaved = []
Array(data["attributes"]).each do |k, v|
@values[k.to_s] = wrap_attribute(k, v)
end
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
# File 'lib/latitude/api/api_resource.rb', line 211
def method_missing(name, *args)
name_s = name.to_s
if name_s.end_with?("=") && args.size == 1
attr_name = name_s.chomp("=")
if read_only_attribute?(attr_name)
raise NoMethodError, "cannot assign to read-only attribute #{attr_name}"
end
return self[attr_name] = args.first
end
return @values[name_s] if @values.key?(name_s) && args.empty?
super
end
|
Instance Attribute Details
#id ⇒ Object
Returns the value of attribute id.
105
106
107
|
# File 'lib/latitude/api/api_resource.rb', line 105
def id
@id
end
|
Returns the value of attribute meta.
105
106
107
|
# File 'lib/latitude/api/api_resource.rb', line 105
def meta
@meta
end
|
#path_params ⇒ Object
Returns the value of attribute path_params.
105
106
107
|
# File 'lib/latitude/api/api_resource.rb', line 105
def path_params
@path_params
end
|
#raw_data ⇒ Object
Returns the value of attribute raw_data.
105
106
107
|
# File 'lib/latitude/api/api_resource.rb', line 105
def raw_data
@raw_data
end
|
#type ⇒ Object
Returns the value of attribute type.
105
106
107
|
# File 'lib/latitude/api/api_resource.rb', line 105
def type
@type
end
|
Class Method Details
.class_url(path_params: {}) ⇒ Object
32
33
34
|
# File 'lib/latitude/api/api_resource.rb', line 32
def class_url(path_params: {})
fill_path(resource_path, path_params)
end
|
.config_source ⇒ Object
63
64
65
|
# File 'lib/latitude/api/api_resource.rb', line 63
def config_source
Thread.current[:latitude_api_config] || Latitude.config
end
|
.construct_from(parsed, opts: {}, path_params: {}) ⇒ Object
56
57
58
59
60
61
|
# File 'lib/latitude/api/api_resource.rb', line 56
def construct_from(parsed, opts: {}, path_params: {})
data = parsed.is_a?(Hash) ? parsed["data"] : nil
raise APIError, "response missing data envelope" unless data.is_a?(Hash)
new(data, meta: parsed["meta"], path_params: path_params, opts: opts)
end
|
.execute_request(method:, path:, query: nil, body: nil, opts: {}, headers: {}) ⇒ Object
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/latitude/api/api_resource.rb', line 42
def execute_request(method:, path:, query: nil, body: nil, opts: {}, headers: {})
options = RequestOptions.wrap(opts)
effective = options.apply_to(config_source)
RequestExecutor.new(effective).execute(
method: method,
path: path,
query: query,
body: body,
headers: ,
idempotency_key: options.idempotency_key,
extra_headers: options.,
)
end
|
75
76
77
78
79
80
81
82
|
# File 'lib/latitude/api/api_resource.rb', line 75
def (params, keys)
= {}
keys.each do |k|
v = params.delete(k) || params.delete(k.to_s)
[k] = v if v
end
end
|
.id_prefix(value = nil) ⇒ Object
20
21
22
23
|
# File 'lib/latitude/api/api_resource.rb', line 20
def id_prefix(value = nil)
@id_prefix = value if value
@id_prefix
end
|
.instance_url(id, path_params: {}) ⇒ Object
36
37
38
39
40
|
# File 'lib/latitude/api/api_resource.rb', line 36
def instance_url(id, path_params: {})
raise ArgumentError, "id is required" if id.nil? || id.to_s.empty?
"#{class_url(path_params: path_params)}/#{URI.encode_www_form_component(id)}"
end
|
.path_param_keys ⇒ Object
84
85
86
|
# File 'lib/latitude/api/api_resource.rb', line 84
def path_param_keys
resource_path.scan(/:(\w+)/).flatten.map(&:to_sym)
end
|
.resource_path(value = nil) ⇒ Object
15
16
17
18
|
# File 'lib/latitude/api/api_resource.rb', line 15
def resource_path(value = nil)
@resource_path = value if value
@resource_path || raise(NotImplementedError, "#{name} must declare resource_path")
end
|
.resource_type(value = nil) ⇒ Object
10
11
12
13
|
# File 'lib/latitude/api/api_resource.rb', line 10
def resource_type(value = nil)
@resource_type = value if value
@resource_type || raise(NotImplementedError, "#{name} must declare resource_type")
end
|
.with_config(config) ⇒ Object
67
68
69
70
71
72
73
|
# File 'lib/latitude/api/api_resource.rb', line 67
def with_config(config)
prev = Thread.current[:latitude_api_config]
Thread.current[:latitude_api_config] = config
yield
ensure
Thread.current[:latitude_api_config] = prev
end
|
Instance Method Details
#==(other) ⇒ Object
Also known as:
eql?
140
141
142
|
# File 'lib/latitude/api/api_resource.rb', line 140
def ==(other)
other.is_a?(self.class) && other.id == @id
end
|
#[](key) ⇒ Object
154
155
156
|
# File 'lib/latitude/api/api_resource.rb', line 154
def [](key)
@values[key.to_s]
end
|
#[]=(key, value) ⇒ Object
158
159
160
161
162
163
|
# File 'lib/latitude/api/api_resource.rb', line 158
def []=(key, value)
key_s = key.to_s
@values[key_s] = wrap_attribute(key_s, value)
@unsaved << key_s unless @unsaved.include?(key_s)
value
end
|
#as_json(*_) ⇒ Object
136
137
138
|
# File 'lib/latitude/api/api_resource.rb', line 136
def as_json(*_)
to_h
end
|
#attributes ⇒ Object
121
122
123
|
# File 'lib/latitude/api/api_resource.rb', line 121
def attributes
@values.each_with_object({}) { |(k, v), h| h[k] = unwrap(v) }
end
|
#changed? ⇒ Boolean
173
174
175
|
# File 'lib/latitude/api/api_resource.rb', line 173
def changed?
!@unsaved.empty?
end
|
#delete(opts = {}) ⇒ Object
Also known as:
destroy
193
194
195
196
|
# File 'lib/latitude/api/api_resource.rb', line 193
def delete(opts = {})
self.class.execute_request(method: :delete, path: resource_url, opts: opts)
self
end
|
#hash ⇒ Object
146
147
148
|
# File 'lib/latitude/api/api_resource.rb', line 146
def hash
[@type, @id].hash
end
|
#inspect ⇒ Object
150
151
152
|
# File 'lib/latitude/api/api_resource.rb', line 150
def inspect
"#<#{self.class.name} id=#{@id.inspect} #{attributes.map { |k, v| "#{k}=#{v.inspect}" }.join(' ')}>"
end
|
#refresh(opts = {}) ⇒ Object
177
178
179
180
181
|
# File 'lib/latitude/api/api_resource.rb', line 177
def refresh(opts = {})
parsed = self.class.execute_request(method: :get, path: resource_url, opts: opts)
update_from(parsed)
self
end
|
#resource_url ⇒ Object
200
201
202
|
# File 'lib/latitude/api/api_resource.rb', line 200
def resource_url
self.class.instance_url(@id, path_params: @path_params)
end
|
#respond_to_missing?(name, include_private = false) ⇒ Boolean
204
205
206
207
208
209
|
# File 'lib/latitude/api/api_resource.rb', line 204
def respond_to_missing?(name, include_private = false)
return true if @values.key?(name.to_s)
return true if name.to_s.end_with?("=") && !read_only_attribute?(name.to_s.chomp("="))
super
end
|
#save(opts = {}) ⇒ Object
183
184
185
186
187
188
189
190
191
|
# File 'lib/latitude/api/api_resource.rb', line 183
def save(opts = {})
return self unless changed?
payload = JSONAPI.encode(type: @type || self.class.resource_type, id: @id, attributes: unsaved_attributes)
parsed = self.class.execute_request(method: :patch, path: resource_url, body: payload, opts: opts)
update_from(parsed)
@unsaved.clear
self
end
|
#to_h ⇒ Object
Also known as:
to_hash
125
126
127
128
129
130
131
132
|
# File 'lib/latitude/api/api_resource.rb', line 125
def to_h
out = {}
out["id"] = @id if @id
out["type"] = @type if @type
out["attributes"] = attributes
out["meta"] = @meta unless @meta.nil? || @meta.empty?
out
end
|
#unsaved_attributes ⇒ Object
169
170
171
|
# File 'lib/latitude/api/api_resource.rb', line 169
def unsaved_attributes
@unsaved.each_with_object({}) { |k, h| h[k] = unwrap(@values[k]) }
end
|
#write_attribute(name, value) ⇒ Object
165
166
167
|
# File 'lib/latitude/api/api_resource.rb', line 165
def write_attribute(name, value)
self[name] = value
end
|