
Consider this example: A transformer bank assembly feature has a totalKva
double field. We want to author an attribute rule such that every time a new transformer unit device is associated with the bank (through a containment association), the new total is updated in the assembly. This total should be equal to the sum of the kva
field values in all transformer content.
On the surface, this rule is simple enough to author as a batch calculation rule on the assembly class. Every time the user runs Evaluate
on the transformer bank, we pull all the transformer content, sum the kva
values, and set the value in the totalKVA
field.
However, this approach has a few limitations:
- It requires an additional step to calculate the value (
Evaluate
). - The value may be incorrect and cannot be trusted until
Evaluate
is run. - It requires a compensating rule to mark the assembly as requiring calculation when a device is attached.
- It is only supported on mobile, file geodatabase, and branch versioned classes.
In this blog, we will author this rule as an immediate calculation rule. To do that, we need to know when an association is added and when an association is removed. The final result will look something like this after we are done.

What happens when an association is added or removed?
When we add a containment association between a parent and child, the associationstatus
field gets updated with the status bit representing the state of the feature. For example:
- When the assembly doesn’t have any content, its
associationstatus
field is set to None (0). - When content is added, the status changes to Container (1), while the content feature
associationstatus
gets updated to Content (4). We will listen to a change for those values in attribute rules and author the rule accordingly. If a change is detected in this field, we can use it to trigger the rule, sum the value, and update the assembly.
What if the assembly is already a container?
The thing to watch for is if the bank is already a container, adding more transformer units won’t update the bank associationstatus
, and as a result, the rule won’t trigger on the bank. However, the content devices’ associationstatus
will always change, providing a hook for the attribute rule to update the bank.
If the content is removed, the associationstatus
is changed to None (0). If content is added, it will be changed to Content (4). In both cases, we can use that knowledge to write an Attribute rule to update the parent container.
So, we will implement all this logic against the content.
How to know if a containment association has been added?
To determine if an association has been added, check the content bit on the $originalFeature.associationStatus
(the value before the update) and the $feature.associationStatus
(the value after the update). If the content bit is not set on the $originalFeature.associationStatus
and it is set on $feature.associationStatus
, we know an association has been added. We will use the bitwise operator & to extract bit 4 (content)
How to know if a containment association has been removed?
To identify if an association has been removed, check the content bit on the $originalFeature.associationStatus
(the value before the update) and the $feature.associationStatus
(the value after the update). If the content bit is set on the $originalFeature.associationStatus
and it’s unset on $feature.associationStatus
, we know an association has been removed.
Next let’s look at how to determine if the parent container for content has been removed.
How to find the parent container if content is removed?
The challenge arises when content is removed from the association, and we can no longer find the container using FeatureSetByAssociation
. When we delete an association in the utility network, it is marked as deleted but not physically deleted. FeatureSetByAssociation
filters out logically deleted associations, making it impossible to find the container using the method after the association is removed. To solve this, we can query the association table directly to locate the parent and mark the update. The association table is just another table that we can query.
You can download the Mobile Geodatabase test data with this rule here.
If you have any questions about this article, Arcade expressions, or attribute rule please visit the ArcGIS Arcade page on the Esri Community site.
Commenting is no longer enabled for this article