Module: Hcloud::EntryLoader

Extended by:
ActiveSupport::Concern
Included in:
Action, Certificate, Datacenter, Firewall, FloatingIP, Image, Iso, LoadBalancer, LoadBalancerType, Location, Network, Pagination, PlacementGroup, PrimaryIP, SSHKey, Server, ServerType, Volume
Defined in:
lib/hcloud/entry_loader.rb

Overview

rubocop:disable Metrics/ModuleLength

Defined Under Namespace

Modules: Collection

Instance Attribute Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



187
188
189
# File 'lib/hcloud/entry_loader.rb', line 187

def method_missing(method, *args, &block)
  _attributes.key?(method) ? _attributes[method] : super
end

Instance Attribute Details

#responseObject

Returns the value of attribute response.



144
145
146
# File 'lib/hcloud/entry_loader.rb', line 144

def response
  @response
end

Instance Method Details

#_attributesObject



183
184
185
# File 'lib/hcloud/entry_loader.rb', line 183

def _attributes
  @_attributes ||= {}.with_indifferent_access
end

#_load(resource) ⇒ Object

rubocop: disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/hcloud/entry_loader.rb', line 227

def _load(resource)
  return if resource.nil?

  @_attributes = {}.with_indifferent_access

  resource.each do |key, value|
    definition = self.class.schema[key]

    if definition == :time
      _update_attribute(key, value ? Time.parse(value) : nil)
      next
    end

    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

#_run_callbacks(order) ⇒ Object



217
218
219
# File 'lib/hcloud/entry_loader.rb', line 217

def _run_callbacks(order)
  self.class._callbacks[order].each { |block| instance_exec(&block) }
end

#_update_attribute(key, value) ⇒ Object



221
222
223
224
# File 'lib/hcloud/entry_loader.rb', line 221

def _update_attribute(key, value)
  _attributes[key] = value
  instance_variable_set("@#{key}", value)
end

#clientObject



155
156
157
# File 'lib/hcloud/entry_loader.rb', line 155

def client
  @client || response&.context&.client
end

#initialize(client = nil, resource = {}) ⇒ Object



146
147
148
149
# File 'lib/hcloud/entry_loader.rb', line 146

def initialize(client = nil, resource = {})
  @client = client
  _load(resource)
end

#inspectObject



151
152
153
# File 'lib/hcloud/entry_loader.rb', line 151

def inspect
  "#<#{self.class.name}:0x#{__id__.to_s(16)} #{_attributes.inspect}>"
end

#prepare_request(url_suffix = nil, **kwargs, &block) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/hcloud/entry_loader.rb', line 171

def prepare_request(url_suffix = nil, **kwargs, &block)
  kwargs[:resource_path] ||= resource_path
  kwargs[:resource_class] ||= self.class
  kwargs[:autoload_action] = true unless kwargs.key?(:autoload_action)

  client.prepare_request(
    [resource_url, url_suffix].compact.join('/'),
    **kwargs,
    &block
  )
end

#resource_pathObject



167
168
169
# File 'lib/hcloud/entry_loader.rb', line 167

def resource_path
  self.class.resource_class.name.demodulize.underscore
end

#resource_urlObject



159
160
161
162
163
164
165
# File 'lib/hcloud/entry_loader.rb', line 159

def resource_url
  if block = self.class.resource_url
    return instance_exec(&block)
  end

  [self.class.resource_class.name.demodulize.tableize, id].compact.join('/')
end

#respond_to_missing?(method, *args, &block) ⇒ Boolean

Returns:

  • (Boolean)


191
192
193
# File 'lib/hcloud/entry_loader.rb', line 191

def respond_to_missing?(method, *args, &block)
  _attributes.key?(method) || super
end

#rollbackObject



213
214
215
# File 'lib/hcloud/entry_loader.rb', line 213

def rollback
  restore_attributes
end

#saveObject



209
210
211
# File 'lib/hcloud/entry_loader.rb', line 209

def save
  update(changes.map { |key, _value| [key.to_sym, _attributes[key]] }.to_h)
end

#update(**kwargs) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/hcloud/entry_loader.rb', line 195

def update(**kwargs)
  context = self
  _run_callbacks(:before)
  prepare_request(j: kwargs, method: :put) do |response|
    response.resource_class.from_response(
      response,
      autoload_action: response.autoload_action
    ).tap do |*_args|
      _run_callbacks(:after)
      context.send(:changes_applied)
    end
  end
end