summaryrefslogtreecommitdiff
path: root/odoo/addons
diff options
context:
space:
mode:
authorRaphael Collet <rco@odoo.com>2019-09-23 13:41:18 +0000
committerRaphael Collet <rco@odoo.com>2019-09-30 15:42:36 +0000
commit4b1cb41cf7a3f936a1e6d00a2bb6a6a29e82d711 (patch)
treec222eb33232a664293d7363cd42d50b87b80341f /odoo/addons
parent333f1087cf50efa4e053e5d9fef0b80e421967f1 (diff)
[FIX] models, fields: cache consistency for one2many fields
Issue: after many2one updates, the cache of the corresponding one2many fields was inconsistent when the latter depends on `active_test`. One of the values in cache was updated, while the other was left intact. We simplify the cache by not making the field depend on context: the cache value contains all the records in the relation (corresponding to `active_test=False`). The value of the field is automatically filtered by the `active` field when the value is accessed. This makes it easier to maintain the cache value, guarantees its consistency, and avoids queries to read the one2many field with `active_test=False`, after having set it with `active_test=True`.
Diffstat (limited to 'odoo/addons')
-rw-r--r--odoo/addons/test_new_api/ir.model.access.csv1
-rw-r--r--odoo/addons/test_new_api/models.py11
-rw-r--r--odoo/addons/test_new_api/tests/test_new_fields.py44
3 files changed, 55 insertions, 1 deletions
diff --git a/odoo/addons/test_new_api/ir.model.access.csv b/odoo/addons/test_new_api/ir.model.access.csv
index 112b72e991d..c0fdba1ea2d 100644
--- a/odoo/addons/test_new_api/ir.model.access.csv
+++ b/odoo/addons/test_new_api/ir.model.access.csv
@@ -41,3 +41,4 @@ access_test_new_api_model_parent,access_test_new_api_model_parent,model_test_new
access_test_new_api_model_child,access_test_new_api_model_child,model_test_new_api_model_child,,1,1,1,1
access_test_new_api_model_child_nocheck,access_test_new_api_model_child_nocheck,model_test_new_api_model_child_nocheck,,1,1,1,1
access_test_new_api_display,access_test_new_api_display,model_test_new_api_display,,1,1,1,1
+access_test_new_api_model_active_field,access_test_new_api_model_active_field,model_test_new_api_model_active_field,,1,1,1,1
diff --git a/odoo/addons/test_new_api/models.py b/odoo/addons/test_new_api/models.py
index 5e1f8d359bf..d12dddd4b8d 100644
--- a/odoo/addons/test_new_api/models.py
+++ b/odoo/addons/test_new_api/models.py
@@ -138,7 +138,7 @@ class Message(models.Model):
@api.constrains('author', 'discussion')
def _check_author(self):
- for message in self:
+ for message in self.with_context(active_test=False):
if message.discussion and message.author not in message.discussion.participants:
raise ValidationError(_("Author must be among the discussion participants."))
@@ -716,3 +716,12 @@ class Mixin(models.AbstractModel):
class ExtendedDisplay(models.Model):
_name = 'test_new_api.display'
_inherit = ['test_new_api.mixin', 'test_new_api.display']
+
+
+class ModelActiveField(models.Model):
+ _name = 'test_new_api.model_active_field'
+ _description = 'A model with active field'
+
+ active = fields.Boolean(default=True)
+ parent_id = fields.Many2one('test_new_api.model_active_field')
+ children_ids = fields.One2many('test_new_api.model_active_field', 'parent_id')
diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py
index 845d5f4e960..7bc2ae547a3 100644
--- a/odoo/addons/test_new_api/tests/test_new_fields.py
+++ b/odoo/addons/test_new_api/tests/test_new_fields.py
@@ -1539,6 +1539,50 @@ class TestX2many(common.TransactionCase):
record_a.unlink()
self.assertFalse(record_a.exists())
+ def test_12_active_test_one2many(self):
+ Model = self.env['test_new_api.model_active_field']
+
+ parent = Model.create({})
+ self.assertFalse(parent.children_ids)
+
+ # create with implicit active_test=True in context
+ child1, child2 = Model.create([
+ {'parent_id': parent.id, 'active': True},
+ {'parent_id': parent.id, 'active': False},
+ ])
+ act_children = child1
+ all_children = child1 + child2
+ self.assertEqual(parent.children_ids, act_children)
+ self.assertEqual(parent.with_context(active_test=True).children_ids, act_children)
+ self.assertEqual(parent.with_context(active_test=False).children_ids, all_children)
+
+ # create with active_test=False in context
+ child3, child4 = Model.with_context(active_test=False).create([
+ {'parent_id': parent.id, 'active': True},
+ {'parent_id': parent.id, 'active': False},
+ ])
+ act_children = child1 + child3
+ all_children = child1 + child2 + child3 + child4
+ self.assertEqual(parent.children_ids, act_children)
+ self.assertEqual(parent.with_context(active_test=True).children_ids, act_children)
+ self.assertEqual(parent.with_context(active_test=False).children_ids, all_children)
+
+ # replace active children
+ parent.write({'children_ids': [(6, 0, [child1.id])]})
+ act_children = child1
+ all_children = child1 + child2 + child4
+ self.assertEqual(parent.children_ids, act_children)
+ self.assertEqual(parent.with_context(active_test=True).children_ids, act_children)
+ self.assertEqual(parent.with_context(active_test=False).children_ids, all_children)
+
+ # replace all children
+ parent.with_context(active_test=False).write({'children_ids': [(6, 0, [child1.id])]})
+ act_children = child1
+ all_children = child1
+ self.assertEqual(parent.children_ids, act_children)
+ self.assertEqual(parent.with_context(active_test=True).children_ids, act_children)
+ self.assertEqual(parent.with_context(active_test=False).children_ids, all_children)
+
def test_search_many2many(self):
""" Tests search on many2many fields. """
tags = self.env['test_new_api.multi.tag']