Difference not() vs. != in entity access XPath constraints

2
Hi all, I have a question regarding the behavior of 'not()' and '!=' with XPath constraints used as entity access. I am working on an app that has a user role (functional administrator) that does user management for most user roles but not all. The user role they are not allowed to manage is the technical administrator user role. The technical administrator is allowed to manage all users. In my app I have the entities 'User' (in the System module) and 'Account' (in the Administration module), Account inherits from User. Both functional administrator and technical administrator are set as module role Administrator for both the System and Administration modules. In Project Security the technical administrator is set to 'All' for User management. The functional administrator is set to 'Selected' with the technical administrator checkbox not checked (the checkbox for '(No user roles)' is checked). I currently have 102 users in my local test environment, 1 is technical administrator without other user roles, 1 is technical administrator with other user roles, and the other 100 have one or more other user roles, or even no user roles at all. In the Administration module the Administrator has Full Read, Full Write access to the Account entity. I will list three XPath constraints on the Account entity and their results on the Account_Overview page (the page itself is just a datagrid with all Accounts, data source XPath but no XPath constraints on the page). 1. No XPath constraint at all. Result 1: functional administrator sees 102 Accounts (not all information is visible but what I care about here is inclusion in the list), technical administrator sees 102 accounts. 2. [not(System.UserRoles = '[%UserRole_TechnicalAdmin%]')] Result 2: functional administrator sees 100 Accounts, technical administrator sees 102 accounts. 3. [System.UserRoles != '[%UserRole_TechnicalAdmin%]'] Result 3: functional administrator sees 101 Accounts (only the technical administrator without other user roles is not included, the technical administrator with other user roles is included), technical administrator sees 102 accounts. So my question is, why is there a difference between the results for 'not()' and '!='? Aren't they supposed to always return the same results? Thanks in advance for answering.   (actual Modeler version: 7.19.1)
asked
4 answers
14

'not()' and '!=' are not guaranteed to return the same result. To illustrate this with an example imagine if you wanted to get all objects from entity Person which are not associated to the current object of entity Team.

//Module.Person[Module.Person_Team!=$currentObject]

will give you only the persons that have a team associated and that team is different than currentObject.

//Module.Person[not(Module.Person_Team=$currentObject)]

will give you the persons who either do not have a team assigned or that team is different than currentObject.

 

A good way to think about XPath constraints is in terms of paths. The first XPath could be read as
"Give me all Persons where there is a path to a Team which is different than $currentObject"

If there is no path between a Person and Team this will return false.
while the second XPath says something completely different, namely:
"Give me all Persons where there is no path via the Person_Team association to $currentObject"

Hope this helps,

answered
3

you tripped into a combination of XPath and Security + System.User Entity.

In general; Access rules on specializations rules over the generalization when dealing with an object of the specialization. Thus in your situation; Access rules on Administration.Account overrule the System.User access rules. 

BUT, there is one exception which is the System.User entity. The access rule on this entity can NOT be overruled. Except through the Security settings => Userrole => manage users with at the most the following user roles (which you found)

Thus your Xpaths at Account level doesn't make any sense ;-)

This explains your question: Could you please explain why the 95 Account objects that are not associated with a user role at all are returned in all 3 situations

answered
1

Hi Jeroen,

!= and not() are definitely not supposed to return the same results, they can but not by definition.

In this case the results are correct:

With the not statement you are saying you can see all accounts with none technical admin roles, even if they have others. With the != satement you are saying you can see all accounts whom have a role not equal to the technical admin role. Since there is 1 account with a technical admin role but also other roles that one is also returned.

 

Hopefully this clarifies things.

answered
1

The following answer was provided on a similar forum question: https://forum.mendix.com/link/questions/2164

"The difference between them is that "!=" compares two values and if they are the same it returns false, if not it returns true. "not()" checks whether certain logic holds true and if so it returns false, if not it returns true. In other words "not()" is a logical operator while "!=" is a comparison operator.

To quote some random page on the internet:
Comparison operators are used in logical statements to determine equality or difference between variables or values.
Logical operators are used to determine the logic between variables or values.

Say x = false and y = false:

not(x and y) returns true;
while x != y returns false;

EDIT (added): Compare: "not(x=100)" to "x!=100" and it should be obvious why using != is superior for comparing two values."

answered