class ApiResource::Resource

Attributes

raw_result[R]

Public Class Methods

all() click to toggle source
# File lib/api-resource/resource.rb, line 77
def self.all
  self.where({})
end
all_pages(params={}) { |arr, page, per_page, total_count| ... } click to toggle source
# File lib/api-resource/resource.rb, line 81
def self.all_pages(params={})
  params  = { page: 1, per_page: default_per_page }.merge(params)
  per_page = params[:per_page].to_i
  page     = params[:page].to_i
  begin
    params[:page] = page
    result         = self.where(params)
    total_count    = result.try :total_count
    arr            = result.to_a
    count          = arr.length
    break if yield(arr, page, per_page, total_count) || (page - 1) * per_page + count >= total_count
    page += 1
  end while true
end
destroy!(id) click to toggle source
# File lib/api-resource/resource.rb, line 101
def self.destroy!(id)
  client(:delete, {}, resource_path, id)
  self
end
filter_submitted_attributes(&block) click to toggle source
# File lib/api-resource/resource.rb, line 46
def self.filter_submitted_attributes(&block)
  self.pre_submit_filter = block if block_given?
end
find(id, params={}) click to toggle source
# File lib/api-resource/resource.rb, line 71
def self.find(id, params={})
  result = client(:get, params, resource_path, id)
  json   = JSON.parse(result)
  self.new(json['data'] || json, result)
end
new(hash=nil, raw_result=nil) click to toggle source
# File lib/api-resource/resource.rb, line 50
def initialize(hash=nil, raw_result=nil)
  self.attributes = hash if hash
  @raw_result = raw_result
end
resource_path() click to toggle source
# File lib/api-resource/resource.rb, line 55
def self.resource_path
  @resource_path || name.to_s.tableize.split('/').last
end
resource_path=(path) click to toggle source
# File lib/api-resource/resource.rb, line 59
def self.resource_path=(path)
  @resource_path = path.gsub(%r{\A/+|/+\Z}, '')
end
where(params) click to toggle source
# File lib/api-resource/resource.rb, line 96
def self.where(params)
  result = client(:get, params, resource_path)
  create_resource_collection(result)
end
with_hmac(api_id, api_secret, options={}) click to toggle source
# File lib/api-resource/resource.rb, line 39
def self.with_hmac(api_id, api_secret, options={})
  self.hmac         = true
  self.api_id       = api_id
  self.api_secret   = api_secret
  self.hmac_options = options
end

Protected Class Methods

build_path(*paths) click to toggle source
# File lib/api-resource/resource.rb, line 264
def self.build_path(*paths)
  paths.map { |p| URI.encode p.to_s.gsub(%r{\A/*(.*?)/*\z}, '\1') }.join('/')
end
build_url(*paths) click to toggle source
# File lib/api-resource/resource.rb, line 259
def self.build_url(*paths)
  raise RuntimeError, 'Empty base_url' if base_url.blank?
  URI::parse(base_url).merge(build_path(*paths)).to_s
end
client(method, params, *paths) click to toggle source
# File lib/api-resource/resource.rb, line 240
def self.client(method, params, *paths)
  url        = build_url(*paths)
  headers    = { accept: :json }
  req_params = { url: url, method: method, headers: headers }
  if method == :get
    # using #to_query instead of URI::encode_www_form to comply with rails convention for query string array values
    req_params[:url] = "#{url}?#{params.to_query}" unless params.to_query.blank?
  else
    req_params[:payload] = params
  end
  req = RestClient::Request.new(req_params)
  if hmac
    req.sign!(api_id, api_secret, hmac_options)
  end
  result = req.execute
  log << result
  result
end
create_log(param) click to toggle source

Create a log that respond to << like a logger param can be 'stdout', 'stderr', a string (then we will log to that file) or a logger (then we return it)

# File lib/api-resource/resource.rb, line 281
def self.create_log(param)
  return param unless param.is_a? String
  case param
    when 'stdout'
      Class.new do
        def <<(obj)
          STDOUT.puts obj
        end
      end.new
    when 'stderr'
      Class.new do
        def <<(obj)
          STDERR.puts obj
        end
      end.new
    else
      Class.new do
        def initialize(file)
          @file = file
        end

        def <<(obj)
          File.open(@file, 'a') { |f| f.puts obj }
        end
      end.new(param)
  end
end
create_resource_collection(result) click to toggle source
# File lib/api-resource/resource.rb, line 202
def self.create_resource_collection(result)
  json = JSON.parse(result)
  ResourceCollection.new(json['data'], json['meta'], self, result)
end
load_class(tableized_class) click to toggle source
# File lib/api-resource/resource.rb, line 207
def self.load_class(tableized_class)
  my_name = name || ancestors.map(&:name).find {|e| e}
  tableized_class = my_name.to_s.tableize.split('/')[0...-1].push(tableized_class).join('/')
  klass = tableized_class && tableized_class.to_s.singularize.classify.constantize rescue nil
  klass if klass && klass < ApiResource::Resource
end
log() click to toggle source
# File lib/api-resource/resource.rb, line 272
def self.log
  self.logger ||= Class.new do
    def <<(_)
    end
  end.new
end
log=(param) click to toggle source
# File lib/api-resource/resource.rb, line 268
def self.log=(param)
  self.logger = create_log(param)
end
method_missing(m, *args, &_) click to toggle source
Calls superclass method
# File lib/api-resource/resource.rb, line 175
def self.method_missing(m, *args, &_)
  case (m)
    when /^by_(.+)/
      my_resource_path = build_path($1.pluralize, args[0], self.resource_path)
      my_model_name = self.model_name
      Class.new(self) do
        self.resource_path = my_resource_path
        @model_name = my_model_name
        def self.model_name
          @model_name
        end
      end
    else
      super
  end
end
model_name() click to toggle source
# File lib/api-resource/resource.rb, line 183
def self.model_name
  @model_name
end

Public Instance Methods

attributes() click to toggle source
# File lib/api-resource/resource.rb, line 130
def attributes
  instance_values.with_indifferent_access.except(:errors, :validation_context, :resource_path)
end
destroy!(options={}) click to toggle source
# File lib/api-resource/resource.rb, line 125
def destroy!(options={})
  submit_resource(resource_path, false, options[:id_attr], :delete)
  self
end
resource_path() click to toggle source
# File lib/api-resource/resource.rb, line 63
def resource_path
  @resource_path ||= self.class.resource_path
end
resource_path=(path) click to toggle source
# File lib/api-resource/resource.rb, line 67
def resource_path=(path)
  @resource_path = path
end
save!(options={}) click to toggle source
# File lib/api-resource/resource.rb, line 106
def save!(options={})
  submit_resource(resource_path, true, options[:id_attr])
  self
end
submit!(options={}) click to toggle source
# File lib/api-resource/resource.rb, line 111
def submit!(options={})
  path = options.fetch(:path, resource_path)
  type = options[:type]
  json = submit_resource(path, false, options[:id_attr])
  meta = json && json['meta']
  type ||= meta && meta['type']
  if type
    returned_type = self.class.load_class(type)
    returned_type.new(json['data'] || json, raw_result)
  else
    self
  end
end

Protected Instance Methods

<<(_) click to toggle source
# File lib/api-resource/resource.rb, line 274
def <<(_)
end
attributes=(hash) click to toggle source
# File lib/api-resource/resource.rb, line 148
def attributes=(hash)
  hash.each do |key, value|
    if respond_to? "#{key}="
      send("#{key}=", value)
    else
      # define method for associated embedded resource(s)
      if value.is_a?(Hash)
        meta, data = value['meta'], value['data'] || value
      else
        meta, data = nil, value
      end

      child_class = self.class.load_class((meta && meta['type']) || key)
      child_value = if child_class && data.is_a?(Hash)
                      child_class.new(data)
                    elsif child_class && data.is_a?(Array)
                      ResourceCollection.new(data, meta, child_class)
                    else
                      data
                    end

      self.class.remove_possible_method(key)
      define_singleton_method(key) { child_value }
    end
  end
end
method_missing(m, *args, &_) click to toggle source
Calls superclass method
# File lib/api-resource/resource.rb, line 192
def method_missing(m, *args, &_)
  case m
    when /^by_(.+)/
      self.resource_path = self.class.build_path($1.pluralize, args[0], resource_path)
      self
    else
      super
  end
end
parse_and_check_error(result) click to toggle source
# File lib/api-resource/resource.rb, line 136
def parse_and_check_error(result)
  return nil if result.blank?
  json        = JSON.parse(result)
  errors_hash = json['errors']
  if errors_hash.is_a?(Hash)
    errors_hash.each { |attr, ary| ary.each { |error| errors.add(attr, error) } }
    nil
  else
    json
  end
end
submit_resource(path, save_attrs=false, id_attr=nil, method=nil) click to toggle source
# File lib/api-resource/resource.rb, line 214
def submit_resource(path, save_attrs=false, id_attr=nil, method=nil)
  raise ResourceError.new(self, 'Attempt to submit invalid resource') unless valid? || method==:delete
  id_attr  = id_attr || default_id_attr
  path     = [path]
  attrs    = attributes
  id_value = attrs[id_attr]
  method   = method || (id_value.nil? ? :post : :put)

  if method != :post && id_value
    path << id_value
    attrs.delete(id_attr)
  end
  attrs = {} if method == :delete
  attrs = pre_submit_filter[attrs] if pre_submit_filter
  begin
    result = self.class.client(method, attrs, *path)
  rescue RestClient::ExceptionWithResponse => e
    result = e.http_body
    raise ResourceError.new(self, "Error executing request #{e.http_code} #{e.http_body}")
  ensure
    json            = parse_and_check_error(result)
    self.attributes = json['data'] || json if json && method == :post && save_attrs
  end
  json
end