class Aptible::Resource::Base

rubocop:disable ClassLength

Attributes

errors[RW]
token[R]

Public Class Methods

adapter() click to toggle source
# File lib/aptible/resource/base.rb, line 27
def self.adapter
  Aptible::Resource::Adapter
end
all(options = {}) click to toggle source
# File lib/aptible/resource/base.rb, line 58
def self.all(options = {})
  out = []
  each_page(options) { |page| out.concat page }
  out
end
basename() click to toggle source
# File lib/aptible/resource/base.rb, line 35
def self.basename
  name.split('::').last.underscore.pluralize
end
belongs_to(relation) click to toggle source
# File lib/aptible/resource/base.rb, line 118
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) click to toggle source
# File lib/aptible/resource/base.rb, line 217
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() click to toggle source
# File lib/aptible/resource/base.rb, line 31
def self.collection_href
  "/#{basename}"
end
create(params = {}) click to toggle source
# File lib/aptible/resource/base.rb, line 91
def self.create(params = {})
  create!(params)
rescue HyperResource::ResponseError => e
  new.tap { |resource| resource.errors = Errors.from_exception(e) }
end
create!(params = {}) click to toggle source
# File lib/aptible/resource/base.rb, line 85
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) click to toggle source
# File lib/aptible/resource/base.rb, line 175
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) click to toggle source

rubocop:disable MethodLength rubocop:disable AbcSize

# File lib/aptible/resource/base.rb, line 138
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: 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: headers
    ) do |page|
      page.each { |entry| block.call entry }
    end
  end
end
define_has_many_setter(relation) click to toggle source

rubocop:disable MethodLength rubocop:disable AbcSize

# File lib/aptible/resource/base.rb, line 191
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 = {}) { |entries| ... } click to toggle source
# File lib/aptible/resource/base.rb, line 39
def self.each_page(options = {})
  return enum_for(:each_page, options) unless block_given?

  href = options[:href] || collection_href
  while href
    # TODO: Breaking here is consistent with the existing behavior of
    # .all, but it essentially swallows an error if the page you're
    # hitting happens to 404. This should probably be addressed in an
    # effort to make this API client more strict.
    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) click to toggle source

rubocop:enable PredicateName

# File lib/aptible/resource/base.rb, line 104
def self.embeds_many(relation)
  define_embeds_many_getters(relation)
  define_has_many_setter(relation)
end
embeds_one(relation) click to toggle source

rubocop:enable AbcSize rubocop:enable MethodLength

# File lib/aptible/resource/base.rb, line 168
def self.embeds_one(relation)
  define_method relation do
    get unless loaded
    objects[relation]
  end
end
field(name, options = {}) click to toggle source
# File lib/aptible/resource/base.rb, line 109
def self.field(name, options = {})
  define_method name do
    self.class.cast_field(attributes[name], options[:type])
  end

  # Define ? accessor for Boolean attributes
  define_method("#{name}?") { !!send(name) } if options[:type] == Boolean
end
find(id, options = {}) click to toggle source
# File lib/aptible/resource/base.rb, line 70
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 = {}) click to toggle source
# File lib/aptible/resource/base.rb, line 77
def self.find_by_url(url, options = {})
  # REVIEW: Should exception be raised if return type mismatch?
  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) click to toggle source
# File lib/aptible/resource/base.rb, line 22
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) click to toggle source

rubocop:disable PredicateName

# File lib/aptible/resource/base.rb, line 98
def self.has_many(relation)
  define_has_many_getters(relation)
  define_has_many_setter(relation)
end
has_one(relation) click to toggle source

rubocop:disable PredicateName

# File lib/aptible/resource/base.rb, line 130
def self.has_one(relation)
  # Better than class << self + alias_method?
  belongs_to(relation)
end
new(options = {}) click to toggle source
Calls superclass method HyperResource::new
# File lib/aptible/resource/base.rb, line 227
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
normalize_params(params = {}) click to toggle source

rubocop: enable AbcSize rubocop:enable MethodLength

# File lib/aptible/resource/base.rb, line 210
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 = {}) click to toggle source
# File lib/aptible/resource/base.rb, line 64
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

Public Instance Methods

_hyperresource_update(params)

rubocop:disable Style/Alias

Alias for: update
adapter() click to toggle source
# File lib/aptible/resource/base.rb, line 247
def adapter
  self.class.adapter
end
bearer_token() click to toggle source
# File lib/aptible/resource/base.rb, line 265
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() click to toggle source
Calls superclass method HyperResource::Modules::HTTP#delete
# File lib/aptible/resource/base.rb, line 290
def delete
  super
rescue HyperResource::ServerError
  raise
rescue HyperResource::ClientError => e
  # Already deleted
  raise unless e.response.status == 404
rescue HyperResource::ResponseError
  # HyperResource chokes on empty response bodies
  nil
end
Also aliased as: destroy
destroy()

rubocop:disable Style/Alias

Alias for: delete
error_html() click to toggle source
# File lib/aptible/resource/base.rb, line 315
def error_html
  errors.full_messages.join('<br />')
end
find_by_url(url_or_href) click to toggle source
# File lib/aptible/resource/base.rb, line 259
def find_by_url(url_or_href)
  resource = dup
  resource.href = url_or_href.gsub(/^#{root}/, '')
  resource.get
end
namespace() click to toggle source
# File lib/aptible/resource/base.rb, line 251
def namespace
  raise 'Resource server namespace must be defined by subclass'
end
populate_default_options!(options) click to toggle source
# File lib/aptible/resource/base.rb, line 235
def populate_default_options!(options)
  options[:root] ||= root_url
  options[:namespace] ||= namespace
  options[:headers] ||= {}
  options[:headers]['Content-Type'] = 'application/json'
end
reload() click to toggle source

NOTE: The following does not update the object in-place

# File lib/aptible/resource/base.rb, line 307
def reload
  self.class.find_by_url(href, token: token, headers: headers)
end
root_url() click to toggle source
# File lib/aptible/resource/base.rb, line 255
def root_url
  raise 'Resource server root URL must be defined by subclass'
end
token=(val) click to toggle source
# File lib/aptible/resource/base.rb, line 242
def token=(val)
  @token = val
  headers['Authorization'] = "Bearer #{bearer_token}"
end
update(params) click to toggle source
# File lib/aptible/resource/base.rb, line 284
def update(params)
  update!(params)
rescue HyperResource::ResponseError
  false
end
Also aliased as: _hyperresource_update
update!(params) click to toggle source

rubocop:enable Style/Alias

# File lib/aptible/resource/base.rb, line 277
def update!(params)
  _hyperresource_update(self.class.normalize_params(params))
rescue HyperResource::ResponseError => e
  self.errors = Errors.from_exception(e)
  raise e
end