[FIX] models: update non-stored inverse field on several records

Issue: when the inverse method writes on a dependency of the first record, it
invalidates the cache of the field for the other records...  Solution: simply
evaluate the inverse method one record at a time.
This commit is contained in:
Raphael Collet
2018-03-12 13:35:57 +01:00
parent 2021f44c0e
commit 2ea3c333e4
2 changed files with 24 additions and 4 deletions
@@ -228,6 +228,13 @@ class TestFields(common.TransactionCase):
self.assertEqual(ewan.parent, cath)
self.assertEqual(ewan.name, "Erwan")
# write on non-stored inverse field on severals records
foo1 = Category.create({'name': 'Foo'})
foo2 = Category.create({'name': 'Foo'})
(foo1 + foo2).write({'display_name': 'Bar'})
self.assertEqual(foo1.name, 'Bar')
self.assertEqual(foo2.name, 'Bar')
record = self.env['test_new_api.compute.inverse']
# create/write on 'foo' should only invoke the compute method
+17 -4
View File
@@ -3560,15 +3560,28 @@ class BaseModel(object):
self._write(old_vals)
if new_vals:
# put the values of pure new-style fields into cache, and inverse them
self.modified(set(new_vals) - set(old_vals))
for record in self:
record._cache.update(record._convert_to_cache(new_vals, update=True))
# put the values of fields into cache, and inverse them
for key in new_vals:
self._fields[key].determine_inverse(self)
field = self._fields[key]
# If a field is not stored, its inverse method will probably
# write on its dependencies, which will invalidate the field
# on all records. We therefore inverse the field one record
# at a time.
batches = [self] if field.store else list(self)
for records in batches:
for record in records:
record._cache.update(
record._convert_to_cache(new_vals, update=True)
)
field.determine_inverse(records)
self.modified(set(new_vals) - set(old_vals))
# check Python constraints for inversed fields
self._validate_fields(set(new_vals) - set(old_vals))
# recompute new-style fields
if self.env.recompute and self._context.get('recompute', True):
self.recompute()