0

I need to write an trigger to allow only update one field on a lead object, not any other fields.

Condition I written is like - if(leadobj.test__c == oldlead.test__c){ leadobj.adderror('can't update any field'); }

But what happen if I update this test field and I update any other field along with the updation of this test field then that other field is also get updated.

It is working fine if I do not update this test field and other field so it throwing this error.

1 Answer 1

3

The behavior you're observing is exactly the behavior that you've defined. As far as we know, you're only checking if one field has changed. How do you expect to be able to stop other fields from changing if you don't check to see if other fields are changing?

Probably the easiest (and perhaps most efficient?) way to determine which fields are changing is to use getPopulatedFieldsAsMap(). As the name implies, you call it on an SObject and you get a Map<String, Object> representing the populated fields.

After removing fields that we don't have control over:

  • system fields like SystemModStamp, LastModifiedDate, LastModifiedBy
  • formula fields

and removing the field that you want to allow changes on, a simple equality check between the two maps will tell you if any of the remaining fields have changed.

So

Account oldAcc = [SELECT FIELDS(STANDARD) FROM Account LIMIT 1];
Account newAcc = oldAcc.clone(true, true, true, true);

Set<String> ignoreFields = new Set<String>{
    'LastModifiedById', 'LastModifiedDate', 'SystemModStamp',
    // let's say that you want to allow the name to change, but not description
    'Name'
};

Map<String, Object> oldFields = oldAcc.getPopulatedFieldsAsMap();
Map<String, Object> newFields = newAcc.getPopulatedFieldsAsMap();

system.assert(oldFields == newFields);

newAcc.Name = 'new name';
newAcc.Description = 'some other description';

newFields = newAcc.getPopulatedFieldsAsMap();

oldFields.keySet().removeAll(ignoreFields);
newFields.keySet().removeAll(ignoreFields);

for(String field :newFields.keySet()){
    system.debug('field: ' + field + ' - ' + oldFields.get(field) + ' vs ' + newFields.get(field));
}

system.assert(oldFields == newFields);

If you either comment out the newAcc.Description = <value>; line, or add it to the ignoreFields set, then the assertion at the bottom will pass. Keep in mind that because we're using Sets here, the field API names are case-sensitive.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.