[FIX] base_action_rule: define patched methods inside a function to fix their closure.

This commit is contained in:
Raphael Collet 2014-07-31 11:17:20 +02:00 committed by Olivier Dony
parent 1e6b7a5f78
commit 130643890d
1 changed files with 71 additions and 55 deletions

View File

@ -156,15 +156,17 @@ class base_action_rule(osv.osv):
""" Wrap the methods `create` and `write` of the models specified by
the rules given by `ids` (or all existing rules if `ids` is `None`.)
"""
updated = False
if ids is None:
ids = self.search(cr, SUPERUSER_ID, [])
for action_rule in self.browse(cr, SUPERUSER_ID, ids):
model = action_rule.model_id.model
model_obj = self.pool[model]
if not hasattr(model_obj, 'base_action_ruled'):
# monkey-patch methods create and write
#
# Note: the patched methods create and write must be defined inside
# another function, otherwise their closure may be wrong. For instance,
# the function create refers to the outer variable 'create', which you
# expect to be bound to create itself. But that expectation is wrong if
# create is defined inside a loop; in that case, the variable 'create'
# is bound to the last function defined by the loop.
#
def make_create():
""" instanciate a create method that processes action rules """
def create(self, cr, uid, vals, context=None, **kwargs):
# avoid loops or cascading actions
if context and context.get('action'):
@ -186,6 +188,10 @@ class base_action_rule(osv.osv):
action_model._process(cr, uid, action, [new_id], context=context)
return new_id
return create
def make_write():
""" instanciate a write method that processes action rules """
def write(self, cr, uid, ids, vals, context=None, **kwargs):
# avoid loops or cascading actions
if context and context.get('action'):
@ -217,8 +223,18 @@ class base_action_rule(osv.osv):
action_model._process(cr, uid, action, post_ids, context=context)
return True
model_obj._patch_method('create', create)
model_obj._patch_method('write', write)
return write
updated = False
if ids is None:
ids = self.search(cr, SUPERUSER_ID, [])
for action_rule in self.browse(cr, SUPERUSER_ID, ids):
model = action_rule.model_id.model
model_obj = self.pool[model]
if not hasattr(model_obj, 'base_action_ruled'):
# monkey-patch methods create and write
model_obj._patch_method('create', make_create())
model_obj._patch_method('write', make_write())
model_obj.base_action_ruled = True
updated = True