lib/hcloud/entry_loader.rb in hcloud-1.0.3 vs lib/hcloud/entry_loader.rb in hcloud-1.1.0
- old
+ new
@@ -72,38 +72,61 @@
ancestors.reverse.find { |const| const.include?(Hcloud::EntryLoader) }
end
def from_response(response, autoload_action: nil)
attributes = response.resource_attributes
- action = response.parsed_json[:action] if autoload_action
+
+ action_resp = _try_load_action(response) if autoload_action
+ return action_resp unless attributes || action_resp.nil?
+
client = response.context.client
if attributes.is_a?(Array)
- results = attributes.map { |item| new(item).tap { |entity| entity.response = response } }
+ results = attributes.map do |item|
+ new(client, item).tap do |entity|
+ entity.response = response
+ end
+ end
results.tap { |ary| ary.extend(Collection) }.response = response
return results
end
- return Action.new(client, action) if attributes.nil? && action
- return new(attributes).tap { |entity| entity.response = response } if action.nil?
+ if action_resp.nil?
+ return new(client, attributes).tap { |entity| entity.response = response }
+ end
[
- Action.new(client, action),
- new(attributes).tap { |entity| entity.response = response }
+ action_resp,
+ new(client, attributes).tap { |entity| entity.response = response }
]
end
- end
- attr_accessor :response
+ def _try_load_action(response)
+ # some API endpoints return a list of actions (e.g. firewall action
+ # apply_to_resources), some a single action (e.g. server action
+ # attach_iso)
+ actions = response.parsed_json[:actions]
+ action = response.parsed_json[:action]
- def initialize(client = nil, kwargs = {})
- if client.is_a?(Hash)
- kwargs = client
- client = nil
+ client = response.context.client
+
+ if actions
+ return actions.map do |act|
+ Action.new(client, act)
+ end
+ elsif action
+ return Action.new(client, action)
+ end
+
+ nil
end
+ end
+ attr_accessor :response
+
+ def initialize(client = nil, resource = {})
@client = client
- _load(kwargs)
+ _load(resource)
end
def inspect
"#<#{self.class.name}:0x#{__id__.to_s(16)} #{_attributes.inspect}>"
end
@@ -177,11 +200,14 @@
def _update_attribute(key, value)
_attributes[key] = value
instance_variable_set("@#{key}", value)
end
+ # rubocop: disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize
def _load(resource)
+ return if resource.nil?
+
@_attributes = {}.with_indifferent_access
resource.each do |key, value|
definition = self.class.schema[key]
@@ -193,10 +219,32 @@
if definition.is_a?(Class) && definition.include?(EntryLoader)
_update_attribute(key, value ? definition.new(client, value) : nil)
next
end
+ # if schema definition is [Class]
+ if definition.is_a?(Array) && definition.first.include?(EntryLoader)
+
+ # just set attribute to an empty array if value is no array or empty
+ if !value.is_a?(Array) || value.empty?
+ _update_attribute(key, [])
+ next
+ end
+
+ if value.first.is_a?(Integer)
+ # If value is an integer, this is the id of an object which's class can be
+ # retreived from definition. Load a future object that can on access retreive the
+ # data from the api and convert it to a proper object.
+ _update_attribute(key, value.map { |id| Future.new(client, definition.first, id) })
+ else
+ # Otherwise the value *is* the content of the object
+ _update_attribute(key, value.map { |item| definition.first.new(client, item) })
+ end
+ next
+ end
+
_update_attribute(key, value.is_a?(Hash) ? value.with_indifferent_access : value)
end
end
+ # rubocop: enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize
end
end