[IMP] mail: make res_model of followers model a related on m2o towards ir.model

When uninstalling a module followers stay in the database because there is no
real link between ir.model and followers. Adding a m2o ensure followers are
correctly removed when uninstalling a module.

res_model fields is kept as a stored related field. This allows to keep
compatibility with almost all code using / searching on followers. Only
followers creation is changed a bit. As follower creation is done mainly
through a dedicated method few changes are required. Yey. Mat should be
happier now.

fix test
This commit is contained in:
Thibault Delavallée
2016-11-23 11:13:18 +01:00
parent d4d00dcd2e
commit 94d2b97da4
3 changed files with 20 additions and 13 deletions
+10 -5
View File
@@ -18,8 +18,12 @@ class Followers(models.Model):
_log_access = False
_description = 'Document Followers'
res_model_id = fields.Many2one(
'ir.model', 'Related Document Model',
index=True, ondelete='cascade',
help='Model of the followed resource')
res_model = fields.Char(
'Related Document Model', required=True, index=True, help='Model of the followed resource')
'Related Document Model Name', index=True, readonly=True, related='res_model_id.model', store=True)
res_id = fields.Integer(
'Related Document ID', index=True, help='Id of the followed resource')
partner_id = fields.Many2one(
@@ -36,6 +40,7 @@ class Followers(models.Model):
:param force: if True, delete existing followers before creating new one
using the subtypes given in the parameters
"""
res_model_id = self.env['ir.model'].search([('model', '=', res_model)], limit=1).id
force_mode = force or (all(data for data in partner_data.values()) and all(data for data in channel_data.values()))
generic = []
specific = {}
@@ -74,9 +79,9 @@ class Followers(models.Model):
gen_new_pids = [pid for pid in partner_data.keys() if pid not in p_exist]
gen_new_cids = [cid for cid in channel_data.keys() if cid not in c_exist]
for pid in gen_new_pids:
generic.append([0, 0, {'res_model': res_model, 'partner_id': pid, 'subtype_ids': [(6, 0, partner_data.get(pid) or default_subtypes.ids)]}])
generic.append([0, 0, {'res_model_id': res_model_id, 'partner_id': pid, 'subtype_ids': [(6, 0, partner_data.get(pid) or default_subtypes.ids)]}])
for cid in gen_new_cids:
generic.append([0, 0, {'res_model': res_model, 'channel_id': cid, 'subtype_ids': [(6, 0, channel_data.get(cid) or default_subtypes.ids)]}])
generic.append([0, 0, {'res_model_id': res_model_id, 'channel_id': cid, 'subtype_ids': [(6, 0, channel_data.get(cid) or default_subtypes.ids)]}])
# create new followers, each document at a time because of existing followers to avoid erasing
if not force_mode:
@@ -90,13 +95,13 @@ class Followers(models.Model):
# subscribe new followers
for new_pid in new_pids:
command.append((0, 0, {
'res_model': res_model,
'res_model_id': res_model_id,
'partner_id': new_pid,
'subtype_ids': [(6, 0, partner_data.get(new_pid) or default_subtypes.ids)],
}))
for new_cid in new_cids:
command.append((0, 0, {
'res_model': res_model,
'res_model_id': res_model_id,
'channel_id': new_cid,
'subtype_ids': [(6, 0, channel_data.get(new_cid) or default_subtypes.ids)],
}))
+8 -6
View File
@@ -25,11 +25,12 @@ class TestMailFollowers(TestMail):
'mail.channel', groups.ids,
{self.user_employee.partner_id.id: [self.mt_mg_nodef.id]},
{test_channel.id: [self.mt_al_nodef.id]})
mail_channel_model_id = self.env['ir.model'].search([('model', '=', 'mail.channel')], limit=1).id
self.assertFalse(specific)
self.assertEqual(len(generic), 2)
self.assertEqual(set([generic[0][2]['res_model'], generic[1][2]['res_model']]),
set(['mail.channel']))
self.assertEqual(set([generic[0][2]['res_model_id'], generic[1][2]['res_model_id']]),
set([mail_channel_model_id]))
self.assertEqual(set(filter(None, [generic[0][2].get('channel_id'), generic[1][2].get('channel_id')])),
set([test_channel.id]))
self.assertEqual(set(filter(None, [generic[0][2].get('partner_id'), generic[1][2].get('partner_id')])),
@@ -39,8 +40,9 @@ class TestMailFollowers(TestMail):
def test_m2o_command_update_selective(self):
test_channel = self.env['mail.channel'].create({'name': 'Test'})
mail_channel_model_id = self.env['ir.model'].search([('model', '=', 'mail.channel')], limit=1).id
groups = self.group_pigs | self.group_public
self.env['mail.followers'].create({'partner_id': self.user_employee.partner_id.id, 'res_model': 'mail.channel', 'res_id': self.group_pigs.id})
self.env['mail.followers'].create({'partner_id': self.user_employee.partner_id.id, 'res_model_id': mail_channel_model_id, 'res_id': self.group_pigs.id})
generic, specific = self.env['mail.followers']._add_follower_command(
'mail.channel', groups.ids,
{self.user_employee.partner_id.id: [self.mt_mg_nodef.id]},
@@ -49,12 +51,12 @@ class TestMailFollowers(TestMail):
self.assertEqual(len(generic), 1)
self.assertEqual(len(specific), 1)
self.assertEqual(generic[0][2]['res_model'], 'mail.channel')
self.assertEqual(generic[0][2]['res_model_id'], mail_channel_model_id)
self.assertEqual(generic[0][2]['channel_id'], test_channel.id)
self.assertEqual(set(generic[0][2]['subtype_ids'][0][2]), set(self.default_group_subtypes.ids))
self.assertEqual(specific.keys(), [self.group_public.id])
self.assertEqual(specific[self.group_public.id][0][2]['res_model'], 'mail.channel')
self.assertEqual(specific[self.group_public.id][0][2]['res_model_id'], mail_channel_model_id)
self.assertEqual(specific[self.group_public.id][0][2]['partner_id'], self.user_employee.partner_id.id)
self.assertEqual(set(specific[self.group_public.id][0][2]['subtype_ids'][0][2]), set([self.mt_mg_nodef.id]))
@@ -118,7 +120,7 @@ class TestMailFollowers(TestMail):
})
with self.assertRaises(IntegrityError):
self.env['mail.followers'].create({
'res_model': 'mail.channel',
'res_model_id': self.env['ir.model'].search([('model', '=', 'mail.channel')], limit=1).id,
'res_id': test_channel.id,
'partner_id': self.user_employee.partner_id.id,
'channel_id': self.group_pigs.id,
+2 -2
View File
@@ -9,7 +9,7 @@
<field name="priority">10</field>
<field name="arch" type="xml">
<tree string="Followers">
<field name="res_model"/>
<field name="res_model_id"/>
<field name="res_id"/>
<field name="partner_id"/>
</tree>
@@ -24,7 +24,7 @@
<sheet>
<group>
<group>
<field name="res_model"/>
<field name="res_model_id"/>
<field name="partner_id"/>
</group>
<group>