How it works...

Record rules are just data records that are loaded in the ir.rule core model. While the file adding them can be anywhere in the module, the convention is for it to be in the security subdirectory. It is common to have a single XML file with both security groups and record rules.

Unlike groups, in the standard modules, the record rules are loaded in an odoo section with the noupdate="1" attribute. With this, those records will not be reloaded on a module upgrade, meaning that manual customization on them is safe and will survive later upgrades.

To stay consistent with the official modules, we should also have our record rules inside a <odoo noupdate="1"> section.

Record rules can be seen from the GUI at the Settings|Technical|Security|Record Rules menu option, as shown in the following screenshot:

The following are the most important record rule fields that were used in this example:

  • Name (name): A descriptive title for the rule.
  • Object (model_id): A reference to the model the rule applies to.
  • Groups (groups): The security groups that the rule applies to. If no security group is specified, the rule is considered global and is applied in a different way (continue with this recipe to learn more about the groups).
  • Domain (domain): A domain expression which is used to filter the records. The rule is only going to applied on these filtered records.

The first record rule we created was for the Library User security group. It uses the [('is_public', '=', True)] domain expression to select only the books that are available publicly. Thus, users with the Library User security group will only be able to see the public books.

The domain expressions used in the record rules run on the server side using ORM objects. Due to this, dot notation can be used on the fields on the left-hand side (the first tuple element). For example, the [('country_id.code', '=', 'IN')] domain expression will only show records that have the country of India.

As record rules are mostly based on the current user, you can use the user recordset in the right-hand side (the third tuple element) of the domain. So, if you want to show the records for the company of the current user, you can use the [('conpany_id', '=', user.company_id.id)] domain. Alternatively, if you want to show the records that are created by the current user, you can use the [('user_id', '=', user.id)] domain.

We want the Librarian security group to be able to see all the books, independent of whether they are public or private. Since it inherits the Library User group, unless we do something about it, it will also be able to see only the public books.

The non-global record rules are joined together using the OR logical operator; each rule adds access and never removes the access. For the Librarian to have access to all the books, we can add to it a record rule to add access for all books, as follows: [('is_public', 'in', [True, False])].

We chose to do it differently here and instead use the [(1, '=', 1)] special rule to unconditionally give access to all book records. While this may seem redundant, remember that otherwise, the Library user rule can be customized in a way that will keep some books out of reach to the Settings user. The domain is special because the first element of a domain tuple must be a field name; this exact case is one of two cases where that is not true. The special domain of [(1, '=', 0)] is never true, but also not very useful in the case of record rules, because this type of rule is used to restrict access to all of the records. The same thing is also possible with access lists.

Record rules are ignored if you activated SUPERUSER. When testing your record rules, ensure that you use another user for that.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset