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
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
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