Class: Xeroizer::Record::BaseModel

Inherits:
Object
  • Object
show all
Includes:
ClassLevelInheritableAttributes, BaseModelHttpProxy
Defined in:
lib/xeroizer/record/base_model.rb

Defined Under Namespace

Modules: InvaidPermissionError Classes: InvalidPermissionError

Constant Summary collapse

ALLOWED_PERMISSIONS =
[:read, :write, :update]
DEFAULT_RECORDS_PER_BATCH_SAVE =
2000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from BaseModelHttpProxy

included

Methods included from ClassLevelInheritableAttributes

included

Constructor Details

#initialize(application, model_name) ⇒ BaseModel

Returns a new instance of BaseModel.



75
76
77
78
# File 'lib/xeroizer/record/base_model.rb', line 75

def initialize(application, model_name)
  @application = application
  @model_name = model_name
end

Instance Attribute Details

#applicationObject (readonly)

Returns the value of attribute application.



26
27
28
# File 'lib/xeroizer/record/base_model.rb', line 26

def application
  @application
end

#model_classObject (readonly)

Returns the value of attribute model_class.



28
29
30
# File 'lib/xeroizer/record/base_model.rb', line 28

def model_class
  @model_class
end

#model_nameObject (readonly)

Returns the value of attribute model_name.



27
28
29
# File 'lib/xeroizer/record/base_model.rb', line 27

def model_name
  @model_name
end

#responseObject (readonly)

Returns the value of attribute response.



29
30
31
# File 'lib/xeroizer/record/base_model.rb', line 29

def response
  @response
end

Class Method Details

.set_api_controller_name(controller_name) ⇒ Object

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.



38
39
40
# 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) ⇒ Object

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



67
68
69
# File 'lib/xeroizer/record/base_model.rb', line 67

def set_optional_xml_root_name(optional_root_name)
  self.optional_root_name = optional_root_name
end

.set_permissions(*args) ⇒ Object

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



45
46
47
48
49
50
51
# 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) ⇒ Object

Method to allow override of the default XML node name.

Default: singularized model name in camel-case.



56
57
58
# 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) ⇒ Object

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



62
63
64
# File 'lib/xeroizer/record/base_model.rb', line 62

def set_xml_root_name(root_name)
  self.xml_root_name = root_name
end

Instance Method Details

#all(options = {}) ⇒ Object

Retreive full record list for this model.

Raises:



118
119
120
121
122
123
# File 'lib/xeroizer/record/base_model.rb', line 118

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_nameObject

Retrieve the controller name.

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



84
85
86
# File 'lib/xeroizer/record/base_model.rb', line 84

def api_controller_name
  self.class.api_controller_name || model_name.pluralize
end

#batch_save(chunk_size = DEFAULT_RECORDS_PER_BATCH_SAVE) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/xeroizer/record/base_model.rb', line 143

def batch_save(chunk_size = DEFAULT_RECORDS_PER_BATCH_SAVE)
  no_errors = true
  @objects = {}
  @allow_batch_operations = true

  yield

  if @objects[model_class]
    objects = @objects[model_class].values.compact
    return false unless objects.all?(&:valid?)
    actions = objects.group_by {|o| o.new_record? ? :http_put : :http_post }
    actions.each_pair do |http_method, records|
      records.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
  end

  @objects = {}
  @allow_batch_operations = false
  no_errors
end

#build(attributes = {}) ⇒ Object

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



93
94
95
96
97
# File 'lib/xeroizer/record/base_model.rb', line 93

def build(attributes = {})
  model_class.build(attributes, self).tap do |resource|
    mark_dirty(resource)
  end
end

#create(attributes = {}) ⇒ Object

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



113
114
115
# File 'lib/xeroizer/record/base_model.rb', line 113

def create(attributes = {})
  build(attributes).tap { |resource| resource.save }
end

#find(id, options = {}) ⇒ Object

Retrieve record matching the passed in ID.

Raises:



134
135
136
137
138
139
140
141
# File 'lib/xeroizer/record/base_model.rb', line 134

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

#first(options = {}) ⇒ Object

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

Raises:



127
128
129
130
131
# File 'lib/xeroizer/record/base_model.rb', line 127

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) ⇒ Object



106
107
108
109
110
# File 'lib/xeroizer/record/base_model.rb', line 106

def mark_clean(resource)
  if @objects and @objects[model_class]
    @objects[model_class].delete(resource.object_id)
  end
end

#mark_dirty(resource) ⇒ Object



99
100
101
102
103
104
# File 'lib/xeroizer/record/base_model.rb', line 99

def mark_dirty(resource)
  if @allow_batch_operations
    @objects[model_class] ||= {}
    @objects[model_class][resource.object_id] ||= resource
  end
end

#parse_response(response_xml, options = {}) ⇒ Object



175
176
177
178
179
180
181
182
# File 'lib/xeroizer/record/base_model.rb', line 175

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)
    end
  end
end