ooor 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,13 +13,21 @@ class OpenObjectResource < ActiveResource::Base
13
13
 
14
14
  cattr_accessor :logger
15
15
  attr_accessor :openerp_id, :info, :access_ids, :name, :openerp_model, :field_ids, :state, #model class attributes assotiated to the OpenERP ir.model
16
- :fields, :fields_defined, :many2one_relations, :one2many_relations, :many2many_relations,
16
+ :fields, :fields_defined, :many2one_relations, :one2many_relations, :many2many_relations, :relations_keys,
17
17
  :openerp_database, :user_id, :scope_prefix, :ooor
18
18
 
19
19
  def class_name_from_model_key(model_key=self.openerp_model)
20
20
  self.scope_prefix + model_key.split('.').collect {|name_part| name_part.capitalize}.join
21
21
  end
22
22
 
23
+ #similar to Object#const_get but for OpenERP model key
24
+ def const_get(model_key)
25
+ klass_name = class_name_from_model_key(model_key)
26
+ klass = Object.const_defined?(klass_name) ? Object.const_get(klass_name) : @ooor.define_openerp_model(model_key, nil, nil, nil, nil, self.scope_prefix)
27
+ klass.reload_fields_definition unless klass.fields_defined
28
+ klass
29
+ end
30
+
23
31
  def reload_fields_definition(force = false)
24
32
  if not (self.to_s.match('IrModel') || self.to_s.match('IrModelFields')) and (force or not @fields_defined)#TODO have a way to force reloading @field_ids too eventually
25
33
  fields = Object.const_get(self.scope_prefix + 'IrModelFields').find(@field_ids)
@@ -36,6 +44,7 @@ class OpenObjectResource < ActiveResource::Base
36
44
  @fields[field.attributes['name']] = field
37
45
  end
38
46
  end
47
+ @relations_keys = @many2one_relations.merge(@one2many_relations).merge(@many2many_relations).keys
39
48
  logger.info "#{fields.size} fields loaded in model #{self.class}"
40
49
  end
41
50
  @fields_defined = true
@@ -113,15 +122,7 @@ class OpenObjectResource < ActiveResource::Base
113
122
  raise
114
123
  end
115
124
 
116
- def method_missing(method_symbol, *arguments) return self.rpc_execute(method_symbol.to_s, *arguments) end
117
-
118
- def load_relation(model_key, ids, scope_prefix, *arguments)
119
- options = arguments.extract_options!
120
- class_name = class_name_from_model_key(model_key)
121
- @ooor.define_openerp_model(model_key, nil, nil, nil, nil, scope_prefix) unless Object.const_defined?(class_name)
122
- relation_model_class = Object.const_get(class_name)
123
- relation_model_class.send :find, ids, :fields => options[:fields] || [], :context => options[:context] || {}
124
- end
125
+ def method_missing(method_symbol, *arguments) self.rpc_execute(method_symbol.to_s, *arguments) end
125
126
 
126
127
 
127
128
  # ******************** finders low level implementation ********************
@@ -226,15 +227,13 @@ class OpenObjectResource < ActiveResource::Base
226
227
  end
227
228
 
228
229
  @relations.each do |k, v| #see OpenERP awkward relations API
230
+ next if v.is_a?(Array) && v.size == 1 && v[0].is_a?(Array) #already casted, possibly before server error!
229
231
  new_rel = self.cast_relation(k, v, self.class.one2many_relations, self.class.many2many_relations)
230
232
  if new_rel #matches a known o2m or m2m
231
233
  @relations[k] = new_rel
232
234
  else
233
235
  self.class.many2one_relations.each do |k2, field| #try to cast the relation to na inherited o2m or m2m:
234
- class_name = self.class.class_name_from_model_key(field.relation)
235
- self.class.ooor.define_openerp_model(field.relation, nil, nil, nil, nil, self.class.scope_prefix) unless Object.const_defined?(class_name)
236
- linked_class = Object.const_get(class_name)
237
- linked_class.reload_fields_definition unless linked_class.fields_defined
236
+ linked_class = self.class.const_get(field.relation)
238
237
  new_rel = self.cast_relation(k, v, linked_class.one2many_relations, linked_class.many2many_relations)
239
238
  @relations[k] = new_rel and break if new_rel
240
239
  end
@@ -244,7 +243,7 @@ class OpenObjectResource < ActiveResource::Base
244
243
 
245
244
  def reload_from_record!(record) load(record.attributes, record.relations) end
246
245
 
247
- def load(attributes, relations={})
246
+ def load(attributes, relations={})#an attribute might actually be a relation too, will be determined here
248
247
  self.class.reload_fields_definition() unless self.class.fields_defined
249
248
  raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
250
249
  @prefix_options, attributes = split_options(attributes)
@@ -253,8 +252,7 @@ class OpenObjectResource < ActiveResource::Base
253
252
  @loaded_relations = {}
254
253
  attributes.each do |key, value|
255
254
  skey = key.to_s
256
- if self.class.many2one_relations.has_key?(skey) || self.class.one2many_relations.has_key?(skey) ||
257
- self.class.many2many_relations.has_key?(skey) || value.is_a?(Array)
255
+ if self.class.relations_keys.index(skey) || value.is_a?(Array)
258
256
  relations[skey] = value #the relation because we want the method to load the association through method missing
259
257
  else
260
258
  case value
@@ -270,6 +268,12 @@ class OpenObjectResource < ActiveResource::Base
270
268
  self
271
269
  end
272
270
 
271
+ def load_relation(model_key, ids, *arguments)
272
+ options = arguments.extract_options!
273
+ related_class = self.class.const_get(model_key)
274
+ related_class.send :find, ids, :fields => options[:fields] || [], :context => options[:context] || {}
275
+ end
276
+
273
277
  def display_available_fields
274
278
  self.class.logger.debug ""
275
279
  self.class.logger.debug "*** DIRECTLY AVAILABLE FIELDS ON OBJECT #{self} ARE: ***\n"
@@ -323,7 +327,7 @@ class OpenObjectResource < ActiveResource::Base
323
327
  self.class.logger.info result["warning"]["title"]
324
328
  self.class.logger.info result["warning"]["message"]
325
329
  end
326
- load({field_name => field_value}.merge(result["value"]))
330
+ load(@attributes.merge({field_name => field_value}).merge(result["value"]), @relations)
327
331
  end
328
332
 
329
333
  #wrapper for OpenERP exec_workflow Business Process Management engine
@@ -337,17 +341,19 @@ class OpenObjectResource < ActiveResource::Base
337
341
  OpenObjectWizard.new(wizard_name, result[0], result[1], [self], self.class.ooor.global_context)
338
342
  end
339
343
 
344
+ def type() method_missing(:type) end #skips deprecated Object#type method
345
+
340
346
 
341
347
  # ******************** fake associations like much like ActiveRecord according to the cached OpenERP data model ********************
342
348
 
343
349
  def relationnal_result(method_name, *arguments)
344
350
  self.class.reload_fields_definition unless self.class.fields_defined
345
351
  if self.class.many2one_relations.has_key?(method_name)
346
- self.class.load_relation(self.class.many2one_relations[method_name].relation, @relations[method_name][0], self.class.scope_prefix, *arguments)
352
+ load_relation(self.class.many2one_relations[method_name].relation, @relations[method_name][0], *arguments)
347
353
  elsif self.class.one2many_relations.has_key?(method_name)
348
- self.class.load_relation(self.class.one2many_relations[method_name].relation, @relations[method_name], self.class.scope_prefix, *arguments)
354
+ load_relation(self.class.one2many_relations[method_name].relation, @relations[method_name], *arguments)
349
355
  elsif self.class.many2many_relations.has_key?(method_name)
350
- self.class.load_relation(self.class.many2many_relations[method_name].relation, @relations[method_name], self.class.scope_prefix, *arguments)
356
+ load_relation(self.class.many2many_relations[method_name].relation, @relations[method_name], *arguments)
351
357
  else
352
358
  false
353
359
  end
@@ -355,28 +361,31 @@ class OpenObjectResource < ActiveResource::Base
355
361
 
356
362
  def method_missing(method_symbol, *arguments)
357
363
  method_name = method_symbol.to_s
358
- return super if attributes.has_key?(method_name) or attributes.has_key?(method_name.first(-1))
359
- if method_name.end_with?('=') && @relations[method_name.sub('=', '')]
360
- @relations[method_name.sub('=', '')] = *arguments
361
- return
362
- end
364
+ is_assign = method_name.end_with?('=')
365
+ method_key = method_name.sub('=', '')
366
+ return super if attributes.has_key?(method_key)
367
+
368
+ @relations[method_key] = arguments[0] and return if is_assign && self.class.relations_keys.index(method_key)
369
+ @attributes[method_key] = arguments[0] and return if is_assign && self.class.fields.keys.index(method_key)
370
+
363
371
  return @loaded_relations[method_name] if @loaded_relations.has_key?(method_name)
364
372
  return false if @relations.has_key?(method_name) and !@relations[method_name]
365
373
 
366
374
  result = relationnal_result(method_name, *arguments)
367
- if result
368
- @loaded_relations[method_name] = result
369
- return result
370
- elsif !self.class.many2one_relations.empty? #maybe the relation is inherited or could be inferred from a related field
371
- self.class.many2one_relations.each do |k, field|
372
- if @relations[k]
373
- @loaded_relations[k] ||= self.class.load_relation(field.relation, @relations[k][0], self.class.scope_prefix, *arguments)
374
- model = @loaded_relations[k]
375
- model.loaded_relations[method_name] ||= model.relationnal_result(method_name, *arguments)
376
- return model.loaded_relations[method_name] if model.loaded_relations[method_name]
377
- end
375
+ @loaded_relations[method_name] = result and return result if result
376
+
377
+ #maybe the relation is inherited or could be inferred from a related field
378
+ self.class.many2one_relations.each do |k, field| #TODO could be recursive eventually
379
+ if @relations[k]
380
+ @loaded_relations[k] ||= load_relation(field.relation, @relations[k][0], *arguments)
381
+ model = @loaded_relations[k]
382
+ model.loaded_relations[method_key] ||= model.relationnal_result(method_key, *arguments)
383
+ return model.loaded_relations[method_key] if model.loaded_relations[method_key]
384
+ elsif is_assign
385
+ klazz = self.class.const_get(field.relation)
386
+ @relations[method_key] = arguments[0] and return if klazz.relations_keys.index(method_key)
387
+ @attributes[method_key] = arguments[0] and return if klazz.fields.keys.index(method_key)
378
388
  end
379
- super
380
389
  end
381
390
 
382
391
  rescue
@@ -172,9 +172,9 @@ module UML
172
172
 
173
173
  def self.get_target(is_reverse, local, enabled_targets, field, model)
174
174
  if (is_reverse && !local) || (!enabled_targets) || enabled_targets.index(field.relation)
175
- target_name = model.class_name_from_model_key(field.relation)
176
- return Object.const_defined?(target_name) ? Object.const_get(target_name) : model.ooor.define_openerp_model(field.relation, nil, nil, nil, nil, model.scope_prefix)
175
+ model.const_get(field.relation)
176
+ else
177
+ false
177
178
  end
178
- return false
179
179
  end
180
180
  end
@@ -77,6 +77,7 @@ class Ooor
77
77
  klass.many2one_relations = {}
78
78
  klass.one2many_relations = {}
79
79
  klass.many2many_relations = {}
80
+ klass.relations_keys = []
80
81
  klass.fields = {}
81
82
  klass.scope_prefix = scope_prefix
82
83
  model_class_name = klass.class_name_from_model_key
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ooor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raphael Valyi - www.akretion.com