[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:30:43 +01:00
parent 42659dc70c
commit c04685e54e
2 changed files with 20 additions and 4 deletions
@@ -278,6 +278,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')
# create/write on 'foo' should only invoke the compute method
log = []
model = self.env['test_new_api.compute.inverse'].with_context(log=log)
+13 -4
View File
@@ -3035,14 +3035,23 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
self.env[model_name].browse(parent_ids).write(parent_vals)
if inverse_vals:
# put the values of inverse fields in cache, and inverse them
self.modified(set(inverse_vals) - set(store_vals))
for record in self:
record._cache.update(record._convert_to_cache(inverse_vals, update=True))
# in case several fields use the same inverse method, call it once
for _inv, fields in groupby(inverse_fields, attrgetter('inverse')):
fields[0].determine_inverse(self)
# 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 all(f.store for f in fields) else list(self)
# put the values of fields in cache, and inverse them
inv_vals = {f.name: inverse_vals[f.name] for f in fields}
for records in batches:
for record in records:
record._cache.update(
record._convert_to_cache(inv_vals, update=True)
)
fields[0].determine_inverse(records)
self.modified(set(inverse_vals) - set(store_vals))