2-phase logic used to constrain DataSource

(constraining scope for DataSources in a multi-tenant app) Consider the following domain model: Entity: Item         * --- 1>    Entity: Tenant                    (each Item is scoped to one Tenant) Entity: Tenant     1 --- *>    Entity: TenantUser           (each Tenant has many TenantUsers, each TenantUser's Name is same as System.User Name) Need to create a DataSource that is all Items belonging to the Tenant associated with the TenantUser who's name is the same as CurrentUser. Normally (in code) this would be a 2-phased approach, 1st: create a variable with the Tenant for the CurrentUser, 2nd: filter the list by this variable How do I accomplish this in an Xpath constraint or Microflow?  
7 answers

Hi GK,


I setup an example with this domain model. Should be what you are explaining


To retrieve all items for the current user you can use this xpath in a microflow.

[MyFirstModule.Item_Tenant/MyFirstModule.Tenant/MyFirstModule.Tenant_Account = $currentUser]


Or use this with a datagrid

[MyFirstModule.Item_Tenant/MyFirstModule.Tenant/MyFirstModule.Tenant_Account = '[%CurrentUser%]']



Hope this helps!


Edit: Just changed my example to this and the xpath was still valid.


Edit 2: I see what you are trying to do now. You want a list of all items that belong to the current users tenant. I was able to do this in a microflow.


[MyFirstModule.Item_Tenant/MyFirstModule.Tenant/Administration.Account_Tenant/Administration.Account/Administration.Account_Tenant = $Account/Administration.Account_Tenant]


This requires you to get the account object in your microflow to do the retrieve. In your case, I think the tenantUser is a generalization of System.User so you would cast that and use the tenantUser association in your retrieve.


Edit 3: You have two options. 

First one is to use xpath as your data source for your listview and have that in a dataview that retrieves the current users tenant (similar to what you have but return the tenant and not the tenant user).

Then you can use the currentobject token in your xpath constraint to get the list.

[MyFirstModule.Item_Tenant/MultiTenantAdministration.Tenant = '[%CurrentObject%]']


second option is to use a microflow as your data source and copy the microflow I showed above.


here is a comparable domain model:

Trying to constrain a list of Items to only those whose Tenant is equal to CurrentUser's tenant. We need to lookup the current user's tenant (phase 1) and then constrain the entity where Item/Tenant.Name = ... (phase 2), but how to achieve this in Xpath or a Microflow?

Every multi-tenant app runs into this, any entity scoped to a user must be constrained to the user's org (tenant). There must be a reasonable solution.


thanks for the examples above but I cannot get the Xpath to work

Here's an shared export of my project, the DataSource in question is in MyFirstModule.Home ListView1

Happy to alter domain models to make this work, it's at a basic level of functionality to prove out multi-tenancy support. The foundations of this are from the multi-tenant module, with help from people in this forum.




I created a test app with the domain model you specified and got it working as (I think) you want.  Here is a package with a data snapshot from 7.18.1  https://www.filehosting.org/file/details/761472/ForumTestApp.mpk

Hope that helps,



On the 'listView1' on MyFirstModule.Home please replace

[MyFirstModule.Item_Tenant/MultiTenantAdministration.Tenant/MultiTenantAdministration.TenantUser_Tenant/MultiTenantAdministration.TenantUser = '[%CurrentUser%]']


[MyFirstModule.Item_Tenant/MultiTenantAdministration.Tenant/MultiTenantAdministration.TenantUser_Tenant = '[%CurrentUser%]']


and it works...



ALSO: The association between TenantUser and User is probably not needed, since TenantUser inherits from User and is therefore the same object with additional attributes inside the TenantUser object. Please have a read here: https://docs.mendix.com/refguide/inheritance-vs.-1-1-association


Thank you to all on this thread who helped sort this out. Much appreciated. Going from the multi-tenant module to a working prototype showing data scoped to individual tenants was not intuitive!

The working prototype is here, for those who run into this same conundrum in the future...

The Xpath expression that worked (starting from MyFirstModule.Item) is: 

[MyFirstModule.Item_Tenant/MultiTenantAdministration.Tenant/MultiTenantAdministration.TenantUser_Tenant = '[%CurrentUser%]']

Unfortunately as you try to enter this Xpath expression in the modeler it turns red (beyond the first /) and leads you to believe that it's invalid, so in this case the modeler trying to help auto-complete an expression gets in the way.


Quick update: rather than setting the Tenant scope constraint at the Widget/Page level, you can set it at the Entity level, this ensures that any page/microflow/etc. using that entity will be scoped to the current user's tenant...