TriggerTypes.ParentFields
Lists the parent (lookup) fields a ParentQuery or PriorParentQuery add-on loads. Read the parents with record.getNewParent(…) or record.getOldParent(…).
Example
cls
public with sharing class ContactOwnerAlignmentWriter implements AfterInsert.Writer, AfterInsert.ParentQuery, AfterInsert.Bypassable {
public static Boolean isBypassed = false;
public Map<SObjectField, TriggerTypes.ParentFields> queryParentsOnAfterInsert() {
return new Map<SObjectField, TriggerTypes.ParentFields>{ Contact.AccountId => TriggerTypes.ParentFields.with(Account.OwnerId).with('Owner', User.IsActive) };
}
public Boolean bypassOnAfterInsertWhen() {
return ContactOwnerAlignmentWriter.isBypassed;
}
public Boolean writeOnAfterInsertWhen(TriggerTypes.InsertRecord record) {
Contact newContact = (Contact) record.getNewSObject();
Account account = (Account) record.getNewParent('Account');
return account?.Owner?.IsActive == true && account.OwnerId != newContact.OwnerId;
}
public void writeOnAfterInsert(TriggerTypes.InsertRecord record, TriggerTypes.UnitOfWork unitOfWork) {
Account account = (Account) record.getNewParent('Account');
unitOfWork.toUpdate(new Contact(Id = record.getId(), OwnerId = account.OwnerId));
}
}The Map Key
The add-on method returns a Map<SObjectField, TriggerTypes.ParentFields>. The key is a lookup field on the trigger object, and the fields belong to the object it points to.
| Key | Read back with |
|---|---|
Contact.AccountId | getNewParent('Account') |
Contact.OwnerId | getNewParent('Owner') |
Invoice__c.Region__c | getNewParent('Region__r') |
The relationship name is case-sensitive.
Methods
Signature
apex
ParentFields with(SObjectField field)
ParentFields with(String relationshipName, SObjectField field)Both take up to five fields, or an Iterable<SObjectField>.
Example
apex
Contact.AccountId => TriggerTypes.ParentFields.with(Account.Name).with('Owner', User.Email)- Start from
TriggerTypes.ParentFields. Everywithreturns the selection, so calls chain. - Grandparents.
with('Owner', User.Email)loads the parent's owner. Read it asparentAccount.Owner.Email.
What Is Loaded
- The declared fields and the
Id. Reading any other field throws anSObjectException. - Declare what you read. Declarations of all handlers are merged, so a handler may see another handler's fields. If that handler is switched off, the field is gone. Declare every field in the handler that reads it.
- Every record, qualified or not. Parents load before any predicate runs, so the query costs SOQL even when nothing qualifies.
- Once per chunk. The parent queries run per chunk, never per record.
- No sharing. Parents are read in system mode, so a handler can see records and fields the user cannot.
- Polymorphic lookups are limited. For
WhatId,WhoIdor anOwnerIdthat can hold a queue, some parents come back null. In after insert, after update and after undelete, a field outside theNameobject makes the query fail.
