Row-level access rules
We know that, by default, records with the active flag set to False are not visible, but a user can access them if needed, using a filter. Suppose that we don't want the regular library users to be able to access inactive books at all. This can be done using record rules — defining filters limiting what particular records a security group can access.
We can find the Record Rules option in the Technical menu, alongside Access Rights.
Record rules are defined in the ir.rule model. As usual, we need to provide a distinctive name. We also need the model they operate on and the domain filter to use for the access restriction. The domain filter uses the usual list of tuples syntax used across Odoo. We will be explaining this domain expression syntax in Chapter 8, Business Logic – Supporting Business Processes.
Usually, rules apply to some particular security groups. In our case, we will make it apply to the employees group. If it applies to no security group in particular, it is considered global (the global field is automatically set to True). Global rules are different, because they impose restrictions that non-global rules can't override.
To add the record rule, we should edit the security/library_security.xml file to add the following XML section inside the <odoo> element:
<data noupdate="1"> <record id="book_user_rule" model="ir.rule"> <field name="name">Library Book User Access</field> <field name="model_id" ref="model_library_book"/> <field name="domain_force"> [('active','=',True)] </field> <field name="groups" eval="[(4,ref('library_group_user'))]"/> </record> </data>
The record rule is inside a <data noupdate="1"> element, meaning that those records will be created on module install, but won't be rewritten on module updates. The point is to allow for these rules to be later customized without the risk of those customizations being lost when performing a module upgrade.
In the groups field, you will also find a special expression. It's a one-to-many relational field, and has a special syntax to operate with. In this case, the (4, x) tuple indicates that x should be appended to the records, and here, x is a reference to the internal user group, identified by base.group_user. This special syntax to write on too many fields is discussed in more detail in Chapter 6, Models – Structuring the Application Data.