m2m-relation-is-label (ODW9501)
Preview (since 0.16.3.25) · Related issues · View source
Derived from the odoo linter.
This rule is unstable and in preview. The --preview flag is required for use.
What it does
Checks for a Many2many whose second positional argument reads as a label rather than
as the name of a table.
Why is this bad?
Many2many takes (comodel_name, relation, column1, column2, string), so the second
positional argument is the name of the relation table, not the label. Many2one takes
(comodel_name, string), and a field written against that shape puts its label where
the table name goes: the label is lost -- Odoo falls back to the one inferred from the
field name -- and the table is created under a name nobody meant to give it, quoted
capitals and spaces included.
Only a value that can not be a table name is reported: one carrying capitals or whitespace. Anything that reads like an identifier is taken at its word.
Example
class SaleCommissionPlanUserWizard(models.TransientModel):
_name = "sale.commission.plan.user.wizard"
user_ids = fields.Many2many("res.users", "Salespersons")
Use instead:
class SaleCommissionPlanUserWizard(models.TransientModel):
_name = "sale.commission.plan.user.wizard"
user_ids = fields.Many2many("res.users", string="Salespersons")
Or name the table as well, which is what Odoo would have generated:
user_ids = fields.Many2many(
"res.users",
"sale_commission_plan_user_wizard_res_users_rel",
"sale_commission_plan_user_wizard_id",
"res_users_id",
"Salespersons",
)
No fix is offered for either shape. On a database that already ran this code the table exists under the label, so correcting the definition renames it: the rows have to be migrated from the old relation table to the new one, which is a decision for a migration script rather than for a linter.