Unlike views, regular data records don't have an XML arch structure and can't be extended using XPath expressions. But they can still be modified replacing the values in their fields.

The <record id="x" model="y"> data loading elements actually perform an insert or update operation on the model y: if model x does not exist, it is created; otherwise, it is updated/written over.

Since records in other modules can be accessed using a <model>.<identifier> global identifier, it's possible for our module to overwrite something that was written before by another module.

The To-Do application included a record rule to ensure that each task would only be visible to the user that created it. But now, with the addition of social features, we need the task followers to also access them. The social network module does not handle this by itself.

Also, now tasks can have users assigned to them, so it makes more sense to have the access rules to work on the responsible user instead of the user who created the task.

The plan would be the same as we did for the menu item: overwrite todo_app.todo_task_user_rule to modify the domain_force field to a new value.

The convention is to keep security-related files in a security subdirectory, so we will create a security/todo_access_rules.xml file with the following content:

<?xml version="1.0" encoding="utf-8"?> 
<odoo> 
  <data noupdate="1"> 
    <record id="todo_app.todo_task_per_user_rule"    
      model="ir.rule"> 
      <field name="name">ToDo Tasks for owner and 
        followers</field> 
      <field name="model_id" ref="model_todo_task"/> 
      <field name="groups" eval="[(4, 
        ref('base.group_user'))]"/> 
      <field name="domain_force"> 
        ['|',('user_id','in', [user.id,False]), 
        ('message_follower_ids','in',
        [user.partner_id.id])] 
      </field> 
    </record> 
  </data> 
</odoo> 

This overwrites the todo_task_per_user_rule record rule from the todo_app module. The new domain filter now makes a task visible to the responsible user, user_id, or to everyone if the responsible user is not set (equals False); it is visible to all the task followers as well.

The record rule runs in a context where a user variable is available and represents the record for the current session user. Since Followers are partners, not users, instead of user.id, we need to use user.partner_id.

The groups field is a to-many relation. Editing data in these fields uses a special notation. The code 4 used here is to append to the list of related records. Also used often is code 6, to instead completely replace the related records with a new list. We well discuss this notation in more detail in Chapter 4Module Data.

The noupdate="1" attribute of the record element means that this record data will only be written on installation actions and will be ignored on module upgrades. This allows for it to be customization, without taking those risk of overwriting customizations and losing them when doing an module upgrade sometime in the future.

As usual, we must not forget to add the new file to data attribute in the the __manifest__.py:

'data': ['views/todo_task.xml', 'security/todo_access_rules.xml'],