Attribute rule to actively transfer data from a related table to it’s parent feature class and vice versa

5429
34
Jump to solution
02-07-2022 04:35 PM
tbearb
by
New Contributor III

Using ArcGIS Enterprise 10.9.1 - Field Maps version 21.4.0. I am curious if we are able to create an attribute rule to transfer a value from a related table to the parent feature class upon record submission?

I currently have attribute rules in place that transfers a water meter’s brand, meter ID, and latest reading from the parent feature class to the related work history table when the record is created. This is successful. I would like to then use another attribute rule on the feature class to automatically update the new meter ID once the new value is typed into the related work history table.

Is this type of workflow supported - actively transferring data from the parent feature to its related table and vice versa? If so, is the attribute rule created in the same manner? Unfortunately I’m not having successful results returning values from the related table back to the parent feature class.

0 Kudos
1 Solution

Accepted Solutions
tbearb
by
New Contributor III

Hi @JohannesLindner I just wanted to reach back out to you as a follow up and say that I finally have the expression working for me! Posted below is what ended up working for me where I had to specifically call out the field I wanted to use for the update. I then just applied the expression to individual fields when I set up the rule. I want to thank you for all your help and getting me on the correct path, it is really appreciated!

// Calculation Attribute Rule on WaterMeterWorkHistory table
// Triggers: Insert, Update
// Execution: Exclude from application evaluation
// Field: New_MeterId
var water_meter = First(FeatureSetByRelationshipName($feature, "WaterMeterTOWorkHistory"))
if($originalfeature.New_MeterId == $feature.New_MeterId) { return null }

// get attributes from water_meter
var old_attributes = {
  "Meter_ID": water_meter.Meter_ID
}

// map the attribute names from the work table to the feature class
var update_attribute_map = [
  ["New_MeterId", "Meter_ID"]
]

// if the new attributes are filled in, add them to the edit request
var updated_attributes = Dictionary()
for(var i in update_attribute_map) {
  var work_att = update_attribute_map[i][0]
  var asset_att = update_attribute_map[i][1]
  var new_att = $feature.New_MeterId
  var old_att = water_meter[asset_att]
  if(!IsEmpty(new_att)) {
    updated_attributes[asset_att] = new_att
  }
}
var edit = [{"className": "WaterMeter", "updates": [{"globalID": water_meter.GlobalID, "attributes": updated_attributes}]}]

return {
  "edit": edit
}

 

View solution in original post

0 Kudos
34 Replies
HusseinNasser2
Esri Contributor

That should be possible, you need to add an attribute rule to the related table. One thing to watch for is cyclic execution and infinite loops. (Parent updates child, child turns out updates parent, which turns out and update child and that goes on.) We detect and protect against such cases but you will need to write the rules such that it has a base condition to quit.

 

0 Kudos
JohannesLindner
MVP Frequent Contributor

It is possible. But you dont define the rule on the feature class, you do it on the work history table.

// Attribute Rule on the work history table
// Triggers: Update
// Field: empty

// do nothing if meter id did not change (so you don't send senseless update requests)
if($originalfeature.MeterID == $feature.MeterID) { return null }

// get the water meter
var water_meter = First(FeatureSetByRelationshipName($feature, "RelationshipName"))
if(water_meter == null) { return null }

// Send a request to update the MeterID in the parent FC
return {
  "edit": [
    {
      "className": "WaterMeterFC",
      "updates": [
        {"globalID": water_meter.GlobalID, "attributes": {"MeterID": $feature.MeterID}}
      ]
    }
  ]
}

 


Have a great day!
Johannes
tbearb
by
New Contributor III

Thank you @HusseinNasser2 and @JohannesLindner for the replies. I think my main issue comes from me placing the attribute rule on the parent feature class rather than the related work history table and there seemed to be some looping occurring. Can you guys please let me know if this is what I should be inputting as an attribute rule? 

Where Old_MeterId is the field on the work history table that stores the original Meter ID from the feature class, New_MeterId is the field on the work history table that is used for input of the new Meter ID after it has been replaced, test.DBO.WaterMeterTOWorkHistory_TEST is the name of the relationship class being used, test.DBO.WaterMeterTEST is the name of the parent feature class, and Meter_ID is the Meter ID field on the parent feature class that is to be updated if a new Meter ID was inputted into the work history table.

// Attribute Rule on the work history table
// Triggers: Update
// Field: empty

// do nothing if meter id did not change (so you don't send senseless update requests)
if($originalfeature.Old_MeterId == $feature.New_MeterId) { return null }

// get the water meter
var water_meter = First(FeatureSetByRelationshipName($feature, "test.DBO.WaterMeterTOWorkHistory_TEST"))
if(water_meter == null) { return null }

// Send a request to update the MeterID in the parent FC
return {
"edit": [
{
"className": "test.DBO.WaterMeterTEST",
"updates": [
{"globalID": water_meter.GlobalID, "attributes": {"MeterID": $feature.Meter_ID}}
]
}
]
}

0 Kudos
JohannesLindner
MVP Frequent Contributor

What's your workflow here? Do you insert the work history record with Old_MeterID and New_MeterID or do you change New_MeterID after the record is already inserted?


Have a great day!
Johannes
0 Kudos
tbearb
by
New Contributor III

Both of the values are inserted at the same time. User input on the New_MeterId field in the work history table and a triggered insert/update immediate attribute rule on the Old_MeterId field to populate the value from the parent FC.

0 Kudos
JohannesLindner
MVP Frequent Contributor

OK, then the rule should trigger on Insert.

// Attribute Rule on the work history table
// Triggers: Insert
// Field: empty


// get the water meter
var water_meter = First(FeatureSetByRelationshipName($feature, "test.DBO.WaterMeterTOWorkHistory_TEST"))
if(water_meter == null) { return null }

// construct the edit parameter, only fill it if meter got replaced
var edit = []
if($feature.New_MeterID != water_meter.MeterID) {
  Push(edit, {
    "className": "test.DBO.WaterMeterTEST"
    "updates": [{"globalID": water_meter.GlobalID, "attributes": {"MeterID": $feature.MeterID}}]
  })
}

// return
return {
  "result": {
    "attributes": {
      "Old_MeterID": water_meter.MeterID,
// you can also copy the other fields here:
//      "Brand": water_meter.Brand,
//      "LatestReading": water_meter.LatestReading,
    }
  },
  "edit": edit
}

Have a great day!
Johannes
tbearb
by
New Contributor III

@JohannesLindnerI really appreciate the help! I will give this a go once our field crew signs off for the day.

You have a great day as well!

-Terry

0 Kudos
tbearb
by
New Contributor III

I am unfortunately still having negative results getting any value to update in the parent feature class. After adding the attribute rule / publishing, when I access the web map again I am now receiving an error when I attempt to create the related record (see attached). I also took a screenshot my settings used for the attribute rule in Pro.

Attribute rule applied:

var water_meter = First(FeatureSetByRelationshipName($feature, "test.DBO.WaterMeterTOWorkHistory_TEST"))
if(water_meter == null) { return null }
var edit = []
if($feature.New_MeterId != water_meter.Meter_ID) {
Push(edit, {
"className": "test.DBO.WaterMeterTEST",
"updates": [{"globalID": water_meter.GlobalID, "attributes": {"Meter_ID": $feature.New_MeterId}}]
})
}
return {
"result": {
"attributes": {
"Old_MeterId": water_meter.Meter_ID,
}
},
"edit": edit
}

tbearb_0-1644359056716.png 

tbearb_1-1644359336187.png

 

 

 

0 Kudos
JohannesLindner
MVP Frequent Contributor

Oh yeah, "Exclude from application evaluation" has to be checked for rules that affect other tables.

Try inserting a record in Pro before publishing, that will give better error messages.


Have a great day!
Johannes