The Reference fields are great, but they don’t have reference integrity: if you delete a record that is pointed by a reference field, this field is not set empty if you don’t implement it, and it isn’t checked if this field is required.
It could be implemented in each module and model that use Reference field… but it will generate repetitive code and some hidden bugs that could be resolved in a general way.
Proposed solution
It is only my first thought about the solution; it requires to be refined or directly discarted by another aproximation.
Option A: a table for each Reference instance
This design has similarities with Property design which has proved ineficient, but in this case it is only used on deletions, so I think could be good enought.
-
A model ir.reference with this fields:
** reference_model: name of model that has the Reference field
** reference_field: name of field that has the Reference field
** referenced_model: name of model that the reference points to
** referenced_id
The value of reference is the concatenation of referenced_model + “,” + referenced_id
** required: boolean -
On ModelStorage.delete, get from ir_reference table the records for its model and deleted instances
** If there is ir.reference with required=True => raise required field exception
** Set to null the reference field of found records and delete them. It should be done AFTER finish all delete() call -
On fields.Reference, the set should maintain the ir.reference records.
** The Reference field should have an option to avoid this behaviour (it won’t generate ir.reference instances) because the developer implements this control? (I’m thinkg, for example, in “shipment” field of moves)
Option B: a table for each Reference field
Similar to A but it doesn’t have a record in ir.reference for each value of fields but only one for each field.
-
A model ir.reference with this fields:
** reference_model: name of model that has the Reference field
** reference_field: name of field that has the Reference field
** referenced_model: name of model that the reference points to
** required: boolean -
On ModelStorage.delete, get from ir_reference table the reference fields that points to its model and search ‘reference_model’ records that points to deleted instances
** If there is ir.reference with required=True => raise required field exception
** Set to null the reference field of found records and delete them. It should be done AFTER finish all delete() call -
On ModelStorage setup maintain the ir.reference records.
** The Reference field should have an option to avoid this behaviour (it won’t generate ir.reference instances) because the developer implements this control? (I’m thinkg, for example, in “shipment” field of moves)