class Xeroizer::Record::BaseModel

Constants

ALLOWED_PERMISSIONS
DEFAULT_RECORDS_PER_BATCH_SAVE

Attributes

application[R]
model_class[W]
model_name[R]
response[R]

Public Class Methods

new(application, model_name) click to toggle source
# File lib/xeroizer/record/base_model.rb, line 75
def initialize(application, model_name)
  @application = application
  @model_name = model_name
  @allow_batch_operations = false
  @objects = {}
end
set_api_controller_name(controller_name) click to toggle source

Method to allow override of the default controller name used in the API URLs.

Default: pluaralized model name (e.g. if the controller name is Invoice then the default is Invoices.

# File lib/xeroizer/record/base_model.rb, line 38
def set_api_controller_name(controller_name)
  self.api_controller_name = controller_name
end
set_optional_xml_root_name(optional_root_name) click to toggle source

Method to add an extra top-level node to use in has_many associations.

# File lib/xeroizer/record/base_model.rb, line 67
def set_optional_xml_root_name(optional_root_name)
  self.optional_xml_root_name = optional_root_name
end
set_permissions(*args) click to toggle source

Set the permissions allowed for this class type. There are no permissions set by default. Valid permissions are :read, :write, :update.

# File lib/xeroizer/record/base_model.rb, line 45
def set_permissions(*args)
  self.permissions = {}
  args.each do | permission |
    raise InvalidPermissionError.new("Permission #{permission} is invalid.") unless ALLOWED_PERMISSIONS.include?(permission)
    self.permissions[permission] = true
  end
end
set_xml_node_name(node_name) click to toggle source

Method to allow override of the default XML node name.

Default: singularized model name in camel-case.

# File lib/xeroizer/record/base_model.rb, line 56
def set_xml_node_name(node_name)
  self.xml_node_name = node_name
end
set_xml_root_name(root_name) click to toggle source

Method to allow override of the default XML root name to use in has_many associations.

# File lib/xeroizer/record/base_model.rb, line 62
def set_xml_root_name(root_name)
  self.xml_root_name = root_name
end

Public Instance Methods

all(options = {}) click to toggle source

Retreive full record list for this model.

# File lib/xeroizer/record/base_model.rb, line 120
def all(options = {})
  raise MethodNotAllowed.new(self, :all) unless self.class.permissions[:read]
  response_xml = http_get(parse_params(options))
  response = parse_response(response_xml, options)
  response.response_items || []
end
api_controller_name() click to toggle source

Retrieve the controller name.

Default: pluaralized model name (e.g. if the controller name is Invoice then the default is Invoices.

# File lib/xeroizer/record/base_model.rb, line 86
def api_controller_name
  self.class.api_controller_name || model_name.pluralize
end
batch_save(chunk_size = DEFAULT_RECORDS_PER_BATCH_SAVE) { || ... } click to toggle source
# File lib/xeroizer/record/base_model.rb, line 182
def batch_save(chunk_size = DEFAULT_RECORDS_PER_BATCH_SAVE)
  @objects = {}
  @allow_batch_operations = true

  begin
    yield

    if @objects[model_class]
      objects = @objects[model_class].values.compact
      save_records(objects, chunk_size)
    end
  ensure
    @objects = {}
    @allow_batch_operations = false
  end
end
build(attributes = {}) click to toggle source

Build a record with attributes set to the value of attributes.

# File lib/xeroizer/record/base_model.rb, line 95
def build(attributes = {})
  model_class.build(attributes, self).tap do |resource|
    mark_dirty(resource)
  end
end
create(attributes = {}) click to toggle source

Create (build and save) a record with attributes set to the value of attributes.

# File lib/xeroizer/record/base_model.rb, line 115
def create(attributes = {})
  build(attributes).tap { |resource| resource.save }
end
create_method() click to toggle source
# File lib/xeroizer/record/base_model.rb, line 208
def create_method
  :http_put
end
find(id, options = {}) click to toggle source

Retrieve record matching the passed in ID.

# File lib/xeroizer/record/base_model.rb, line 150
def find(id, options = {})
  raise MethodNotAllowed.new(self, :all) unless self.class.permissions[:read]
  response_xml = @application.http_get(@application.client, "#{url}/#{CGI.escape(id)}", options)
  response = parse_response(response_xml, options)
  result = response.response_items.first if response.response_items.is_a?(Array)
  result.complete_record_downloaded = true if result
  result
end
find_in_batches(options = {}) { |results| ... } click to toggle source

allow invoices to be process in batches of 100 as per xero documentation developer.xero.com/documentation/api/invoices/

# File lib/xeroizer/record/base_model.rb, line 129
def find_in_batches(options = {}, &block)
  options[:page] ||= 1
  while results = all(options)
    if results.any?
      yield results
      options[:page] += 1
    else
      break
    end
  end
end
first(options = {}) click to toggle source

Helper method to retrieve just the first element from the full record list.

# File lib/xeroizer/record/base_model.rb, line 143
def first(options = {})
  raise MethodNotAllowed.new(self, :all) unless self.class.permissions[:read]
  result = all(options)
  result.first if result.is_a?(Array)
end
mark_clean(resource) click to toggle source
# File lib/xeroizer/record/base_model.rb, line 108
def mark_clean(resource)
  if @objects and @objects[model_class]
    @objects[model_class].delete(resource.object_id)
  end
end
mark_dirty(resource) click to toggle source
# File lib/xeroizer/record/base_model.rb, line 101
def mark_dirty(resource)
  if @allow_batch_operations
    @objects[model_class] ||= {}
    @objects[model_class][resource.object_id] ||= resource
  end
end
model_class() click to toggle source
# File lib/xeroizer/record/base_model.rb, line 90
def model_class
  @model_class ||= Xeroizer::Record.const_get(model_name.to_sym)
end
parse_response(response_xml, options = {}) click to toggle source
# File lib/xeroizer/record/base_model.rb, line 199
def parse_response(response_xml, options = {})
  Response.parse(response_xml, options) do | response, elements, response_model_name |
    if model_name == response_model_name
      @response = response
      parse_records(response, elements, paged_records_requested?(options), (options[:base_module] || Xeroizer::Record))
    end
  end
end
save_records(records, chunk_size = DEFAULT_RECORDS_PER_BATCH_SAVE) click to toggle source
# File lib/xeroizer/record/base_model.rb, line 159
def save_records(records, chunk_size = DEFAULT_RECORDS_PER_BATCH_SAVE)
  no_errors = true
  return false unless records.all?(&:valid?)

  actions = records.group_by {|o| o.new_record? ? create_method : :http_post }
  actions.each_pair do |http_method, records_for_method|
    records_for_method.each_slice(chunk_size) do |some_records|
      request = to_bulk_xml(some_records)
      response = parse_response(self.send(http_method, request, {:summarizeErrors => false}))
      response.response_items.each_with_index do |record, i|
        if record and record.is_a?(model_class)
          some_records[i].attributes = record.non_calculated_attributes
          some_records[i].errors = record.errors
          no_errors = record.errors.nil? || record.errors.empty? if no_errors
          some_records[i].saved!
        end
      end
    end
  end

  no_errors
end

Protected Instance Methods

paged_records_requested?(options) click to toggle source
# File lib/xeroizer/record/base_model.rb, line 215
def paged_records_requested?(options)
  options.has_key?(:page) and options[:page].to_i >= 0
end
parse_records(response, elements, paged_results, base_module) click to toggle source

Parse the records part of the XML response and builds model instances as necessary.

# File lib/xeroizer/record/base_model.rb, line 220
def parse_records(response, elements, paged_results, base_module)
  elements.each do | element |
    new_record = model_class.build_from_node(element, self, base_module)
    if element.attribute('status').try(:value) == 'ERROR'
      new_record.errors = []
      element.xpath('.//ValidationError').each do |err|
        new_record.errors << err.text.gsub(/^\s+/, '').gsub(/\s+$/, '')
      end
    end
    new_record.paged_record_downloaded = paged_results
    response.response_items << new_record
  end
end
parse_save_response(response_xml) click to toggle source

Parse the response from a create/update request.

# File lib/xeroizer/record/base_model.rb, line 242
def parse_save_response(response_xml)
  response = parse_response(response_xml)
  record = response.response_items.first if response.response_items.is_a?(Array)
  if record && record.is_a?(self.class)
    @attributes = record.attributes
  end
  self
end
to_bulk_xml(records, builder = Builder::XmlMarkup.new(:indent => 2)) click to toggle source
# File lib/xeroizer/record/base_model.rb, line 234
def to_bulk_xml(records, builder = Builder::XmlMarkup.new(:indent => 2))
  tag = (self.class.optional_xml_root_name || model_name).pluralize
  builder.tag!(tag) do
    records.each {|r| r.to_xml(builder) }
  end
end