Carefully Crafted Attribute Rules

In our Simplifying Editing Workflows we briefly mention the benefits of Attribute Rules. In this post I’d like to take a deeper dive into the ins and outs of writing Attribute Rules. Some quick foundational information for those not familiar with attribute rules, they are:

  1. Written using the Arcade scripting language
  2. Applied at the feature class level and executed at the feature service level
  3. More flexible than typical database level constraints because they can include complex logic
  4. Can be specific to asset types or subtypes and can be applied conditionally based on other attribute values

The intention here is to make it quicker and easier for editors to do their work while reducing redundant tasks and/or enforcing basic logic to prevent data entry errors. Unfortunately, even very simple rules can have unintended and undesirable consequences.

  • Prevent Editing – A constraint rule that prevents null values in a field will prevent any edits including geometry to that feature if no value is provided.
  • Slow Performance – Rules that are triggered when updates are made might be triggered by scheduled tasks or by geoprocessing tools like the field calculator.
  • Overwrite Edits – Updates and Inserts behave differently, a calculation rule that is intended to help populate default values when new features are created, can easily overwrite an attribute value that an editor has modified manually.

Let’s review a couple of ways to build your logic to ensure that your attribute rules do exactly what is intended.

Task 1

Create a constraint rule that prevents the user from creating or editing a feature without entering a value for installation date.

if (IsEmpty($feature.installationdate) == true)
   {
      return {'errorMessage':'The field installation date cannot be empty.'};
   }
return True;

The rule above seems simple enough, it constrains the user from doing any editing unless an installation date is entered. But let’s suppose the business also needs to create features that are proposed prior to being installed, technically there is no install date.  The rule as written above makes it tedious for editors and requires them to enter a date that might not be correct.  Editors might be forced to enter a fictitious date as a placeholder or a date when the assets are expected to be installed and could lead to inaccurate data.  Using additional logic will allow the business to create features without fudging the installation date.

var ls= $feature.lifecyclestatus;
if (ls=='installed')
   {
      if (IsEmpty($feature.installationdate) == true)
         {
            return{'errorMessage':'The field installation date cannot be empty if the lifecycle status is installed.'};
         }
      return True;
   }
return True;

The rule above adds nested logic to require an installation date only if the lifecycle status is ‘installed’. It works better to ensure that editors are not prevented from entering features with no installation date, if the lifecycle status is something other than ‘installed’.  A couple extra lines is all it takes to more accurately support the business workflow.

Task 2

Create a calculation rule to perform a spatial query and intersect polygons for service area.  When a feature is created or edited, attributes from the intersected service area polygon can be used to automatically populate values in the feature that is being edited.

var fsServiceCenter = FeatureSetByName($datastore, "dbo.ServiceCenters", ["Service_Center_ID"]);
var fsServiceIntersect = Intersects(fsServiceCenter, $Feature);
var servicecenter = First(fsServiceIntersect);

if (servicecenter == null) return {"errorMessage": "Service Center not found, check location."};
return servicecenter.Service_Center_ID;

The above script uses the intersects function to return a value for Service Center.  It works great and prevents the user from creating or editing assets that are located outside a service area polygon.  But, let’s suppose that our enterprise database synchronizes daily with a workorder system. This process updates several thousand assets per day.  Performing the intersect query is not necessary and can slow the update. Adding a little more logic can help.

var fsServiceCenter = FeatureSetByName($datastore, "dbo.ServiceCenters", ["Service_Center_ID"]);
var fsServiceIntersect = Intersects(fsServiceCenter, $Feature);
var servicecenter = First(fsServiceIntersect);

if (IsEmpty($feature. Service_Center_ID) == true)
   {
      if (servicecenter == null) return {"errorMessage": "Service Center not found, check location."};
      return servicecenter.Service_Center_ID;
   }
return $feature.Service_Center_ID;

The additional if clause checks to see if the ‘service center id’ field is empty and will run the intersects query only if it is empty.  This additional check will prevent unnecessary spatial queries when using field calculations or running synchronization scripts.  Also, the calculation script above doubles as a constraint rule and will prevent editors from creating assets unless they intersect a service center.  Let’s suppose some of assets can be correctly located outside service center polygons, and you don’t want to prevent the editors from creating these features. A simple modification will allow editors to create assets that might be outside of a service center, and when no service center id is available it will populate the service center ID field with the string ‘None’.

var fsServiceCenter = FeatureSetByName($datastore, "dbo.ServiceCenters", ["Service_Center_ID"]);
var fsServiceIntersect = Intersects(fsServiceCenter, $Feature);
var servicecenter = First(fsServiceIntersect);

if (IsEmpty($feature.Service_Center_ID) == true)
   {
      if (servicecenter == null) return 'None';
      return servicecenter.Service_Center_ID;
   }
return $feature.Service_Center_ID;

Attribute rules are powerful and can help improve productivity and data integrity. Understanding the complexity of the business and their editing-workflows is critical prior to implementing any new rules.  Remember, taking a little more time and adding a little more logic to your rules will ensure that your rules improve the process and don’t cause any unintended or undesirable consequences.