Odoo 12 Development Essentials
上QQ阅读APP看书,第一时间看更新

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.

While developing,  noupdate="1" can be a nuisance, since, if you need to fix your rule, a module upgrade won't rewrite the data in the database. Because of this, you might want to temporarily have  noupdate="0" during development, until you're happy with the data file.

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.