[FIX] core: update cache on parent_path when updated
Purpose ======= The parent_path is invalidated from cache when computing it from scratch (with method `_parent_store_compute`) but not when it is recomputed (method `_parent_store_update`). The issue is that a computed field depending on 'parent_path' won't receive the updated value using the cache, and could lead to inconsistencies if the developer is not aware of that. Specification ============= On `_parent_store_update`, set the new value of 'parent_path' in the cache before marking the records as modified. task-2766452 closes odoo/odoo#84795 X-original-commit: 861854a7598f31c0b971560484e3eb576af006b4 Signed-off-by: Raphael Collet <rco@odoo.com> Signed-off-by: Rémy Voet <ryv@odoo.com> Co-authored-by: Rémy Voet <ryv@odoo.com>
This commit is contained in:
committed by
Rémy Voet (ryv)
co-authored by
Rémy Voet
parent
a503073b96
commit
c983ae0fa2
@@ -18,6 +18,7 @@ class Category(models.Model):
|
||||
color = fields.Integer('Color Index')
|
||||
parent = fields.Many2one('test_new_api.category', ondelete='cascade')
|
||||
parent_path = fields.Char(index=True, unaccent=False)
|
||||
depth = fields.Integer(compute="_compute_depth")
|
||||
root_categ = fields.Many2one(_name, compute='_compute_root_categ')
|
||||
display_name = fields.Char(compute='_compute_display_name', recursive=True,
|
||||
inverse='_inverse_display_name')
|
||||
@@ -45,6 +46,11 @@ class Category(models.Model):
|
||||
current = current.parent
|
||||
cat.root_categ = current
|
||||
|
||||
@api.depends('parent_path')
|
||||
def _compute_depth(self):
|
||||
for cat in self:
|
||||
cat.depth = cat.parent_path.count('/') - 1
|
||||
|
||||
def _inverse_display_name(self):
|
||||
for cat in self:
|
||||
names = cat.display_name.split('/')
|
||||
|
||||
@@ -3063,6 +3063,24 @@ class TestParentStore(common.TransactionCase):
|
||||
with self.assertRaises(UserError):
|
||||
self.cats(1, 3).write({'parent': self.cats(9).id})
|
||||
|
||||
def test_compute_depend_parent_path(self):
|
||||
self.assertEqual(self.cats(7).depth, 3)
|
||||
self.assertEqual(self.cats(8).depth, 3)
|
||||
self.assertEqual(self.cats(9).depth, 3)
|
||||
|
||||
# change parent of node to have 2 parents
|
||||
self.cats(7).parent = self.cats(2)
|
||||
self.assertEqual(self.cats(7).depth, 2)
|
||||
|
||||
# change parent of node to root
|
||||
self.cats(7).parent = False
|
||||
self.assertEqual(self.cats(7).depth, 0)
|
||||
|
||||
# change grand-parent of nodes
|
||||
self.cats(6).parent = self.cats(0)
|
||||
self.assertEqual(self.cats(8).depth, 2)
|
||||
self.assertEqual(self.cats(9).depth, 2)
|
||||
|
||||
|
||||
class TestRequiredMany2one(common.TransactionCase):
|
||||
|
||||
|
||||
+7
-3
@@ -4383,11 +4383,15 @@ Fields:
|
||||
FROM {0} node
|
||||
WHERE node.id IN %s
|
||||
AND child.parent_path LIKE concat(node.parent_path, '%%')
|
||||
RETURNING child.id
|
||||
RETURNING child.id, child.parent_path
|
||||
"""
|
||||
cr.execute(query.format(self._table), [prefix, tuple(self.ids)])
|
||||
modified_ids = {row[0] for row in cr.fetchall()}
|
||||
self.browse(modified_ids).modified(['parent_path'])
|
||||
|
||||
# update the cache of updated nodes, and determine what to recompute
|
||||
updated = dict(cr.fetchall())
|
||||
records = self.browse(updated)
|
||||
self.env.cache.update(records, self._fields['parent_path'], updated.values())
|
||||
records.modified(['parent_path'])
|
||||
|
||||
def _load_records_write(self, values):
|
||||
self.write(values)
|
||||
|
||||
Reference in New Issue
Block a user