ooor 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/app/models/open_object_resource.rb +47 -38
- data/lib/app/models/uml.rb +3 -3
- data/lib/ooor.rb +1 -0
- metadata +1 -1
@@ -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)
|
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
|
-
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
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
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
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
|
data/lib/app/models/uml.rb
CHANGED
@@ -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
|
-
|
176
|
-
|
175
|
+
model.const_get(field.relation)
|
176
|
+
else
|
177
|
+
false
|
177
178
|
end
|
178
|
-
return false
|
179
179
|
end
|
180
180
|
end
|
data/lib/ooor.rb
CHANGED