class Xeroizer::Record::BaseModel
Constants
- ALLOWED_PERMISSIONS
- DEFAULT_RECORDS_PER_BATCH_SAVE
Attributes
Public Class Methods
# 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
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
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 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
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
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
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
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
# 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 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 (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
# File lib/xeroizer/record/base_model.rb, line 208 def create_method :http_put end
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
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
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
# 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
# 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
# File lib/xeroizer/record/base_model.rb, line 90 def model_class @model_class ||= Xeroizer::Record.const_get(model_name.to_sym) end
# 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
# 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
# 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 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 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
# 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