Select to view content in your preferred language

Attribute rule to modify a different attribute in a different feature than the triggering feature and field

154
2
2 weeks ago
Rohanrajan
Emerging Contributor

Hi,

Scenario: I have a feature class and two different subtypes A and B, these two subtypes are related in a way that field 'source_id' will have the id of a source feature in subtype A and that id (123) will be populated in the 'source' field of the subtype B features. 

And there is a field 'children' in subtype A that has the count of the features with 'source = 123' will be populated in the field 'children'.

So I tried creating an attribute rule that does this

 1. Upon INSERT/UPDATE/DELETE

2. If any one of the subtype B features gets inserted or updated or deleted 'source = 456'

3. I get a featureset where 'subtype = B And source = 456' and get the count of the returned features 

4. Get the featureset where 'subtype = A And source_id = 456' and populate the count in the field 'children'

Problem: 

The field children in the triggering feature (subtype = B) gets updated.

 

Q. How do I configure my attribute rule so that I can get trigger from one feature and make edits through attribute rule in another feature

0 Kudos
2 Replies
Robert_LeClair
Esri Esteemed Contributor

Hi @Rohanrajan - I "think" this example "edit another feature class with a calculation rule" would be a good start to write the script.  The key is the 'edit' keyword as described here - Attribute rule dictionary keywords—ArcGIS Pro | Documentation

0 Kudos
AlfredBaldenweck
MVP Regular Contributor

You want a dictionary keyword.

You can use them to edit the current feature, another feature in the same table, or one or more features in a different table or tables entirely.

Crucially, when setting up the rule, don't set it on any field for the output.

Here's an example of a rule that buffers a line automatically, updating any buffer that already exists as well as doing a field calculation on the feature to transform the measurement from feet to meters and miles.

//Reference: https://pro.arcgis.com/en/pro-app/latest/help/data/geodatabases/overview/attribute-rule-dictionary-keywords.htm
var rels = FeatureSetByRelationshipName($feature, "rowlines_rowbuffs", ["GlobalID"])
// Get list of buffers to be updated
var ups = []
var miles = $feature.Buffer_size_ft/5280
var meters = $feature.Buffer_size_ft *.3048
for (var rel in rels){
    Push(ups, rel["globalID"])
}
// Return if the buffer field is empty
if (isEmpty($feature.Buffer_size_ft)){
    return
}
// Buffer line by buffer field.
var geo = Geometry($feature)
geo = Buffer(geo, $feature.Buffer_size_ft, "feet")

// This part is tricky
// Construct pieces of your return dictionary
// Assume that it will be adding, like the other three attribute rules before this. 
var edit = [{"attributes": {"Serial_Num": $feature.Serial_Num, 
                                                  "Buffer_size_ft": $feature.Buffer_size_ft,
                                                  "relUUID": $feature.GlobalID
                                                 },
                                    "geometry": geo
                                   }]
var edittype = "adds"

// However, if there's already a buffer, change the dictionary 
// to be updates and specify which record you want.
if (Count(ups)>0){
    edit = [{"globalID" : ups[0], // In this case, we only want one buffer per line, 
                                  // so there should only be one in the list.
             "attributes": {"Serial_Num": $feature.Serial_Num, 
                            "Buffer_size_ft": $feature.Buffer_size_ft,
                            "relUUID": $feature.GlobalID
                                                 },
                             "geometry": geo
                             }]
    edittype = "updates"
}

// Create the return dictionary with instructions to populate two different fields
// then add in the editing instructions from above.
var retDict = {
               "result": {"attributes": {"Buffer_meter": meters,
                                         "Buffer_miles": miles,}
                          },
               "edit": [{"className": "rowbuffs"}]}
// I have to do it this way because if you just add in 
// edittype:edit, it thinks the key is "edittype"
retDict["edit"][0][edittype] = edit
console(retDict)
/*
retDict = {"result": {"attributes": {"Buffer_meter": meters,
                                     "Buffer_miles": miles,}
                          },
           "edit": [{"className": "rowbuffs",
                     "updates": [{"globalID" : ups[0],
                                  "attributes": {
                                                 "Serial_Num": $feature.Serial_Num, 
                                                 "Buffer_size_ft": $feature.Buffer_size_ft,
                                                 "relUUID": $feature.GlobalID
                                                 },
                                  "geometry": geo
                                  }]
                    }]
          }
*/
return retDict

 

Here's a file GDB (>=3.5) where this rule was used, as well as several rules that were earlier versions of this rule. The rules are mostly in order but reordering them is really hard so I kind of gave up.

It should be 

  1. GenerateID (was just testing this rule out, you can ignore it)
    1. This is the only reason this geodatabase needs to be in 3.5, because the rule was introduced in this version. Everything else can be at Version>=2.7
  2. Calculate meters solo
  3. Calculate miles solo
  4. Meters and miles together
  5. Buffers no limits (make a new buffer each time the geometry changes)
  6. buffers delete (delete and replace the buffer when the geometry changes)
  7. buffers  add and update (add or update buffer when geometry changes)
  8. Buffers add and update, calc different units (see above)