class Apicasso::Brush

A module to inject Autoracing data consumption behavior

Public Class Methods

all(opts = {}) click to toggle source

Lists all objects from APIcasso of this class. Can receive a hash of parameters to be passed as query string into the APIcasso instance

# File lib/apicasso/brush.rb, line 99
def self.all(opts = {})
  query = "?per_page=-1#{url_encode(opts)}&#{self.getter_include}"
  url = URI.parse("#{resource_url}#{query}")
  http = Net::HTTP.new(url.host, url.port)

  response = JSON.parse(retrieve(http, get_request(url)).read_body).deep_symbolize_keys
  brush_collection(response)
end
brush_on(resource_url = nil, opts = {}) click to toggle source

A plugger to classes on a service using APIcasso. Receives the URL to get an object from the API.

# File lib/apicasso/brush.rb, line 8
    def self.brush_on(resource_url = nil, opts = {})
      if resource_url.nil?
        raise Exception, "Configuration error.\nYou should pass the URL for your APIcasso resource as the first parameter\n# => brush_on 'https://my.api/path/to/resource'"
      elsif opts[:token].nil?
        raise Exception, "Configuration error.\nYou should pass a token option to authenticate.\n# => brush_on 'https://my.api/path/to/resource', token: '5e1o5ba77ca7f0d4'"
      end

      # Interface into options set on initialization
      class_eval <<-RUBY, __FILE__, __LINE__ + 1
        # Token used to connect into resource's APIcasso instance
        def self.apicasso_token
          "#{opts[:token]}"
        end
        # Base URL to resource, used to query from APIcasso instance
        def self.resource_url
          "#{resource_url}"
        end
        # Method that sets a default include query on this resource
        def self.getter_include
          "include=#{opts[:include].try(:map, &:to_s).try(:join, ',')}" if "#{opts[:include]}".present?
        end
      RUBY
    end
create(opts = {}) click to toggle source

Create objects, either using batch or individual request.

# File lib/apicasso/brush.rb, line 109
def self.create(opts = {})
  if opts.is_a? Array
    url = URI.parse("#{resource_url.chomp('/' + resource_url.split('/').last)}/batch_create")
    http = Net::HTTP.new(url.host, url.port)

    brush_collection(JSON.parse(retrieve(http, post_request(url, opts)).read_body))
  else
    url = URI.parse(resource_url.to_s)
    http = Net::HTTP.new(url.host, url.port)

    new(nil, JSON.parse(retrieve(http, post_request(url, opts)).read_body))
  end
end
find(id) click to toggle source

Finds a resource with the given id

# File lib/apicasso/brush.rb, line 148
def self.find(id)
  new(id)
end
find_by(opts = {}) click to toggle source

Finds a object based on attributes conditions

# File lib/apicasso/brush.rb, line 136
def self.find_by(opts = {})
  where(opts).try(:[], 0)
end
find_by!(opts = {}) click to toggle source

Finds a object based on attributes conditions, raises not found exception when query has no match

# File lib/apicasso/brush.rb, line 142
def self.find_by!(opts = {})
  object = find_by(opts)
  raise ::Exception, 'Not Found' if object.nil?
end
find_or_create_by(opts = {}) click to toggle source

Finds object based on opts finder, if no record is find it creates one using individual request.

# File lib/apicasso/brush.rb, line 125
def self.find_or_create_by(opts = {})
  raise ::Exception, 'Pass attributes as hash' unless opts.is_a? Hash

  object = nil
  unless object = find_by(opts)
    object = create(opts)
  end
  object
end
new(id = nil, object = {}) click to toggle source

Constructor that can receive the ID of the object to search as first parameter and/or object attributes as second parameters

# File lib/apicasso/brush.rb, line 34
def initialize(id = nil, object = {})
  @object = object
  @id = id || object[:id]
  instantiate if id.present? && !object.present?
end
update(opts = {}) click to toggle source

Create objects, either using batch or individual request.

# File lib/apicasso/brush.rb, line 84
def self.update(opts = {})
  if opts.is_a? Array
    url = URI.parse("#{resource_url.chomp('/' + resource_url.split('/').last)}/batch_update")
    http = Net::HTTP.new(url.host, url.port)

    brush_collection(JSON.parse(retrieve(http, patch_request(url)).read_body))
  elsif opts.is_a? Hash
    object = find(opts[:id])
    object.update(opts)
  end
end
where(query = '', opts = {}) click to toggle source

Returns an array of objects that matches a given query, which is the first parameter. This query can be a string of an ransack URL query or a hash where the keys would be *_eq operators.

# File lib/apicasso/brush.rb, line 155
def self.where(query = '', opts = {})
  query = "?per_page=-1#{stringfy_ransackable(query)}#{url_encode(opts)}&#{getter_include}"
  url = URI.parse("#{resource_url}#{query}")
  http = Net::HTTP.new(url.host, url.port)

  response = JSON.parse(retrieve(http, get_request(url)).read_body).deep_symbolize_keys
  brush_collection(response)
end

Private Class Methods

brush_collection(response) click to toggle source
# File lib/apicasso/brush.rb, line 255
def brush_collection(response)
  (response.is_a?(Hash) ? response[:entries] : response).map do |object|
    new(nil, object)
  end
end
check_success(status) click to toggle source
# File lib/apicasso/brush.rb, line 214
def check_success(status)
  case status
  when '404', 404
    raise ::Exception, 'Resource not found, are you sure you have configured your `brush_on` URL'
  when '401', 401
    raise ::Exception, 'Invalid Token'
  when '403', 403
    raise ::Exception, "Not authorized to #{request::METHOD} on resource"
  else
    raise ::Exception, 'Error when fetching from APIcasso' if status.to_i > 400
  end
end
delete_request(url) click to toggle source
# File lib/apicasso/brush.rb, line 227
def delete_request(url)
  request = Net::HTTP::Delete.new(url)
  request['Authorization'] = "Token token=#{apicasso_token}"
  request
end
get_request(url) click to toggle source
# File lib/apicasso/brush.rb, line 233
def get_request(url)
  request = Net::HTTP::Get.new(url)
  request['Authorization'] = "Token token=#{apicasso_token}"
  request
end
patch_request(url, body) click to toggle source
# File lib/apicasso/brush.rb, line 239
def patch_request(url, body)
  request = Net::HTTP::Patch.new(url)
  request['Authorization'] = "Token token=#{apicasso_token}"
  request['Content-Type'] = 'application/json'
  request.body = { resource_url.split('/').last.singularize => body }.to_json
  request
end
post_request(url, body) click to toggle source
# File lib/apicasso/brush.rb, line 247
def post_request(url, body)
  request = Net::HTTP::Post.new(url)
  request['Authorization'] = "Token token=#{apicasso_token}"
  request['Content-Type'] = 'application/json'
  request.body = { resource_url.split('/').last.singularize => body }.to_json
  request
end
retrieve(http, request) click to toggle source
# File lib/apicasso/brush.rb, line 208
def retrieve(http, request)
  response = http.request(request)
  check_success response.code
  response
end
stringfy_ransackable(query = nil) click to toggle source
# File lib/apicasso/brush.rb, line 190
def stringfy_ransackable(query = nil)
  if query.is_a? String
    '&' + query
  elsif query.is_a? Hash
    '&q={' + query.map do |key, value|
      "\"#{key}_eq\": \"#{value}\""
    end.join(',') + '}'
  end
end
url_encode(query = {}) click to toggle source
# File lib/apicasso/brush.rb, line 200
def url_encode(query = {})
  return if query.nil?

  '&' + query.map do |key, value|
    "#{key}=#{value}"
  end.join('&')
end

Public Instance Methods

attributes() click to toggle source

Attributes from this object

# File lib/apicasso/brush.rb, line 51
def attributes
  @object
end
delete()
Alias for: destroy
destroy() click to toggle source

Destroys current object on APIcasso

# File lib/apicasso/brush.rb, line 165
def destroy
  @object = @id = delete_object(URI.parse(getter_url))
end
Also aliased as: delete
getter_url() click to toggle source

Base getter URL for current resource

# File lib/apicasso/brush.rb, line 46
def getter_url
        self.class.resource_url + @id.to_s + '?' + self.class.getter_include.to_s
end
instantiate() click to toggle source

Instantiates the object by getting it from APIcasso

# File lib/apicasso/brush.rb, line 41
def instantiate
  objectify! URI.parse(getter_url)
end
method_missing(meth, *args, &block) click to toggle source

Overriding `method_missing` to enable fields being retrieved from @object

Calls superclass method
# File lib/apicasso/brush.rb, line 56
def method_missing(meth, *args, &block)
  @object[meth.to_sym] || super
end
objectify!(url) click to toggle source

Reloads @object variable by receiving the URL used to get the object

# File lib/apicasso/brush.rb, line 66
def objectify!(url)
  @object = get_object(url)
end
reload!() click to toggle source

Reloads the object by getting from APIcasso

# File lib/apicasso/brush.rb, line 61
def reload!
  instantiate if @id.present?
end
save() click to toggle source

Saves current object to APIcasso

# File lib/apicasso/brush.rb, line 71
def save
  @object = save_object(URI.parse(getter_url)) if @object.is_a? Hash
  @id = @object[:id]
end
update(opts = {}) click to toggle source

Updates current object to APIcasso

# File lib/apicasso/brush.rb, line 77
def update(opts = {})
  @object.merge(opts)
  @object = save_object(URI.parse(getter_url)) if @object.is_a? Hash
  @id = @object[:id]
end

Private Instance Methods

delete_object(url) click to toggle source
# File lib/apicasso/brush.rb, line 184
def delete_object(url)
  http = Net::HTTP.new(url.host, url.port)
  self.class.retrieve(http, self.class.delete_request(url))
end
get_object(url) click to toggle source
# File lib/apicasso/brush.rb, line 173
def get_object(url)
  http = Net::HTTP.new(url.host, url.port)
  JSON.parse(self.class.retrieve(http, self.class.get_request(url)).read_body).deep_symbolize_keys
end
save_object(url) click to toggle source
# File lib/apicasso/brush.rb, line 178
def save_object(url)
  http = Net::HTTP.new(url.host, url.port)
  meth = (@id.present? ? 'patch' : 'post')
  JSON.parse(self.class.retrieve(http, self.class.send("#{meth}_request", url, @object)).read_body).deep_symbolize_keys
end