Create a trigger that calculates the count of child records related to parent records. Implement a custom rollup summary field using an Apex trigger. Establish a rollup summary on a lookup relationship using a trigger.
To illustrate the issue, let’s consider an example. We have a lookup relationship between Accounts and Contacts, and we need to determine the number of child records associated with each account.
Before crafting a trigger to count the number of child records, it’s important to take into account several scenarios.
- When any new child record is inserted, we need to update the rollup summary field on the parent record. (After Insert)
- When the parent id is updated on the child record, we need to update the rollup summary field on the parent record. (After Update)
- For any child record deleted, we need to update the rollup summary field on the parent record. (Before Delete)
- For any child record undeleted, we need to update the rollup summary field on the parent record. (After Undelete)
Please make a note of the following:
- Always follow salesforce best practices while writing code. (Apex Trigger and Apex Class(Trigger Helper class )
- For after update always query both old and new parent records to update the count. We generally query only new parent records.
- Write a trigger to count the number of related child records on parent records.
Apex Trigger
trigger RollUpCountTrigger on Contact (after insert, after update, after delete, after undelete) { //when child record inserted and undeleted if(trigger.isAfter && (trigger.isInsert || trigger.isUndelete)){ RollUpCountTrigger.countContact(trigger.new); } else if(trigger.isAfter && trigger.isDelete){ // when child record deleted RollUpCountTrigger.countContact(trigger.old); } if(trigger.isAfter && trigger.isUpdate){ //when parent id updated on child records RollUpCountTrigger.countContactUpdate(trigger.new,trigger.oldMap); } }
Trigger Helper Class (Apex Class)
public class RollUpCountTrigger { public static void countContact(List<Contact> newList){ //for insert, undelete and undelete Set<id> accountIds = new Set<id>(); List<Account> listOfAccounts = new List<Account>(); For(Contact con : newList){ if(con.AccountId != null){ accountIds.add(con.accountId); //new parent id } } if(!accountIds.isEmpty()){ List<Account> listAccount = [SELECT Id, Name, Number_of_Contacts__c, (SELECT Id FROM Contacts) FROM Account WHERE Id IN :accountIds]; For(Account acc : listAccount){ if(acc.Contacts.size()>0) acc.Number_of_Contacts__c = acc.Contacts.size(); // count of child records listOfAccounts.add(acc); } if(listOfAccounts.size()>0) update listOfAccounts; //update parent records } } public static void countContactUpdate(List<Contact> newList,Map<Id,Contact> oldMap){ //for update Set<id> accountIds = new Set<id>(); List<Account> listOfAccounts = new List<Account>(); For(Contact con : newList){ if(con.AccountId != null){ accountIds.add(con.accountId); // new parent id } if(con.AccountId != oldMap.get(con.Id).AccountId){ accountIds.add(oldMap.get(con.Id).AccountId); // old parent id } } if(!accountIds.isEmpty()){ List<Account> listAccount = [SELECT Id, Name, Number_of_Contacts__c, (SELECT Id FROM Contacts) FROM Account WHERE Id IN :accountIds]; For(Account acc : listAccount){ if(acc.Contacts.size()>0) acc.Number_of_Contacts__c = acc.Contacts.size(); // count of child records listOfAccounts.add(acc); } if(listOfAccounts.size()>0) update listOfAccounts; // update parent records } } }
For any Queries/doubts comment below and for quick responses on LinkedIn and Twitter.