lib/billimatic/resources/base.rb
require "billimatic/resources/hooks"
module Billimatic
module Resources
class Base
include Wisper::Publisher
extend Hooks
attr_accessor :http
def self.crud(*args)
@crud ||= args
end
def initialize(http)
@http = http
end
def collection_name
@collection_name ||= underscore_pluralized_klass_name
end
def parsed_body(response)
MultiJson.load(response.body)
rescue MultiJson::ParseError
{}
end
def create(params)
crud_request do
http.post(resource_base_path, { body: params }) do |response|
respond_with_entity(response)
end
end
end
def show(id)
crud_request do
http.get("#{resource_base_path}/#{id}") do |response|
respond_with_entity(response)
end
end
end
def list
crud_request do
http.get(resource_base_path) do |response|
respond_with_collection(response)
end
end
end
def list_by_organization(id)
http.get("/organizations/#{id}#{resource_base_path}") do |response|
respond_with_collection response
end
end
def show_by_organization(organization_id, entity_id)
http.get(
"/organizations/#{organization_id}#{resource_base_path}/#{entity_id}"
) { |response| respond_with_entity response }
end
def destroy(id)
crud_request do
http.delete("#{resource_base_path}/#{id}") do |response|
response.code == 204
end
end
end
def update(id, params)
crud_request do
http.put("#{resource_base_path}/#{id}", { body: params }) do |response|
respond_with_entity(response)
end
end
end
notify :create, :destroy
protected
def crud_request
method = caller_locations(1,1)[0].label
if self.class.crud.include?(:all) || self.class.crud.include?(method.to_sym)
yield
else
raise RuntimeError, "#{base_klass} do not implement the #{method} method"
end
end
def respond_with_collection(response, class_name = base_klass)
parsed_body(response)[collection_name].map do |item|
entity_klass(class_name).new(item)
end
end
def respond_with_entity(response, naked_klass = entity_klass)
naked_klass.new(parsed_body(response)[underscored_klass_name])
end
def respond_with_openstruct(response)
OpenStruct.new(MultiJson.load(response.body))
end
def resource_base_path
@resource_base_path ||= "/#{collection_name}"
end
def base_klass
@base_klass ||= self.class.name.split('::').last
end
def entity_klass(class_name = base_klass)
@entity_klass ||= Billimatic::Entities.const_get(class_name.to_sym)
end
def underscore_pluralized_klass_name
"#{underscored_klass_name}s"
end
def underscored_klass_name
base_klass.gsub(/(.)([A-Z])/, '\1_\2').downcase
end
end
end
end