Write a trigger to update a field on a child record to a default value if the child record is the only child of the parent.

Let’s say – The parent object is Account, The child object is Contact, We want to update the child field Status__c to ‘Primary’ only if that contact is the only contact related to the parent Account.

Trigger:

trigger SetDefaultStatusForOnlyChild on Contact (after insert, after delete, after undelete) {
    Set<Id> accountIds = new Set<Id>();

    if (Trigger.isInsert || Trigger.isUndelete) {
        for (Contact con : Trigger.new) {
            if (con.AccountId != null) {
                accountIds.add(con.AccountId);
            }
        }
    }

    if (Trigger.isDelete) {
        for (Contact con : Trigger.old) {
            if (con.AccountId != null) {
                accountIds.add(con.AccountId);
            }
        }
    }

    if (accountIds.isEmpty()) return;

    // Query all contacts grouped by account
    Map<Id, List<Contact>> accountToContactsMap = new Map<Id, List<Contact>>();
    for (Contact con : [
        SELECT Id, AccountId, Status__c
        FROM Contact
        WHERE AccountId IN :accountIds
    ]) {
        if (!accountToContactsMap.containsKey(con.AccountId)) {
            accountToContactsMap.put(con.AccountId, new List<Contact>());
        }
        accountToContactsMap.get(con.AccountId).add(con);
    }

    List<Contact> contactsToUpdate = new List<Contact>();
    for (Id accId : accountToContactsMap.keySet()) {
        List<Contact> contacts = accountToContactsMap.get(accId);
        if (contacts.size() == 1) {
            Contact onlyChild = contacts[0];
            if (onlyChild.Status__c != 'Primary') {
                onlyChild.Status__c = 'Primary';
                contactsToUpdate.add(onlyChild);
            }
        }
    }

    if (!contactsToUpdate.isEmpty()) {
        update contactsToUpdate;
    }
}

Key Concepts:

  • Trigger Events: We use after insert, after delete, and after undelete because:
    • Insert may result in the first or second child.
    • Delete may leave only one child behind.
    • Undelete may change the count from one to two or more.

Leave a Comment

Your email address will not be published. Required fields are marked *