Record API
Every handler method that takes one record gets a TriggerTypes record interface. It wraps the new and old rows, the declared parents and the related records.
Record Interfaces
| Context | Record | Validator error method gets | Collection |
|---|---|---|---|
| BeforeInsert | InsertRecord | RejectableInsertRecord | InsertRecords |
| AfterInsert | InsertRecord | InsertRecords | |
| BeforeUpdate | UpdateRecord | RejectableUpdateRecord | UpdateRecords |
| AfterUpdate | UpdateRecord | UpdateRecords | |
| BeforeDelete | DeleteRecord | RejectableDeleteRecord | DeleteRecords |
| AfterDelete | DeleteRecord | DeleteRecords | |
| AfterUndelete | UndeleteRecord | UndeleteRecords |
All interfaces are nested in TriggerTypes.
Methods
| Member | Insert | Rejectable Insert | Update | Rejectable Update | Delete | Rejectable Delete | Undelete |
|---|---|---|---|---|---|---|---|
getId(), getRelated(providerName) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
getNewSObject(), getNewParent(lookupField) | ✓ | ✓ | ✓ | ✓ | ✓ | ||
getOldSObject(), getOldParent(lookupField) | ✓ | ✓ | ✓ | ✓ | |||
put(field, value) | ✓ | ✓ | |||||
addError(error), addError(field, error) | ✓ | ✓ | ✓ | ||||
| value checks and record type checks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| change detection | ✓ | ✓ |
A missing member is a compile error, such as isChanged in an insert handler.
getId()is null in before insert.getNewSObject()is the live row in before insert and before update. In the after contexts it is read-only.getOldSObject()is read-only. Stop a delete withrecord.addError(…)in a BeforeDelete.Validator.getNewParent(Contact.AccountId)returns the parent a ParentQuery loaded, or null.getOldParentreads PriorParentQuery. Pass the lookup field you declared. The row itself holds only the lookup Id:getNewSObject().Accountis null.putworks only in before insert and before update. In after insert and after update it compiles but throws aFinalExceptionthat nothing can catch. Change saved records with a Writer.addError(field, error)shows the error at record level onNameand address fields. The record is still rejected.
Value Checks
equals, doesNotEqual, isIn, isNotIn, contains, doesNotContain, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty, isBlank, isNotBlank, isTrue, isFalse, greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo.
- They read the new row. In the delete contexts they read the old row.
- They see earlier changes. In before contexts, a value set by an earlier handler with
putcounts. - They never throw on null. Comparisons such as
lessThanare false for null. - Case.
equalsandisInignore case for text.contains,startsWithandendsWithare case-sensitive. 0andfalseare values. They are not null, empty or blank.
Change Detection
Update contexts only: isChanged, isAnyChanged, areAllChanged, isChangedTo, isChangedToNotNull, isChangedFrom, isChangedFromTo.
isAnyChangedandareAllChangedtake 2 to 5 fields or anIterable<SObjectField>.- Text comparison ignores case.
'Doe'to'DOE'is not a change.
Record Type
isRecordType(developerName) and isNotRecordType(developerName) compare by developer name, not label. They cost no SOQL.
- Objects without record types throw a
TriggerLibException. - A misspelled name is not caught. An unknown name resolves to no Id, so
isRecordTypeis true for rows without aRecordTypeId, such as in-memory test rows, and false for all others.
