Introduction:
In this blog post, we will see an example on how to roll up child values on a parent record. This applies to both master-detail and lookup relationships.
In this example. we will demonstrate updating total contacts count on Account. This will be done using roll up summary apex trigger and aggregate query. The same logic can be used update the child record count on a parent record in a lookup relationship. This will be achieved using an aggregate query and maps approach.
Example Scenario:
Imagine a company using Salesforce to manage customer accounts (Account records) and their related contacts (Contact records). Each Account has a field (Number_of_Contacts__c) to track the total number of associated Contact records.
A Contact might be added, updated, deleted, or restored. The Number_of_Contacts__c field on the related Account must then reflect these changes accurately. For example:
Adding a New Contact: If a new Contact is linked to an Account. The contact count on that Account should go up. The account should reflect this increase.
Updating a Contact: If a Contact is reassigned to another Account, the original Account’s contact count should decrease. The new Account’s count should increase.
- Adding a New Contact: If a new Contact is linked to an Account. The contact count on that Account should go up. The account should reflect this increase.
- Updating a Contact Parent: If a Contact is reassigned to another Account, the original Account’s contact count should decrease. The new Account’s count should increase.
- Deleting a Contact: When a Contact is removed, the associated Account’s contact count should decrease.
- Restoring a Contact: If a deleted Contact is restored, the Account’s contact count should include it again.
This ensures that Account managers always have up-to-date information about the number of Contacts linked to each Account. The UpdateContactCountOnAccount trigger automates these updates, improving data accuracy and minimizing manual effort.
Trigger Overview:
The UpdateContactCountOnAccount trigger is designed to maintain the Number_of_Contacts__c field on Account records. It dynamically updates this field based on changes to related Contact records.
What It Updates:
Number_of_Contacts__c: Reflects the total number of Contact records linked to each Account.
When It Runs:
The trigger fires during the following DML events on Contact records:
- ✨ Insert: A new Contact is added.
- 🔄 Update: A Contact is reassigned to a different Account.
- ❌ Delete: A Contact is removed.
- ↩️ Undelete: A previously deleted Contact is restored.
How It Works:
Here’s a step-by-step breakdown of the trigger:
- Declare a Set for Account IDs:
- A set (
accountIds) is initialized to collect the IDs of Accounts whoseNumber_of_Contacts__cfield needs updating.
- A set (
- Identify Relevant Account IDs for Insert or Undelete Events:
- For insert or undelete events, the trigger iterates through the
Trigger.newcollection. - If a Contact has a non-null
AccountId, its associated Account ID is added to the set.
- For insert or undelete events, the trigger iterates through the
- Identify Relevant Account IDs for Delete Events:
- For delete events, the trigger loops through the
Trigger.oldcollection. - It adds the
AccountIdof each deleted Contact to the set if it is not null.
- For delete events, the trigger loops through the
- Handle Updates to Account IDs:
- For update events, the trigger compares the
AccountIdinTrigger.oldMapandTrigger.new. - If the
AccountIdchanges, both the old and new Account IDs are added to the set. - If the
AccountIdremains unchanged, no action is needed unless additional logic is introduced.
- For update events, the trigger compares the
- Exit if No Account IDs to Update:
- If the set of
accountIdsis empty, the trigger exits early to avoid unnecessary processing.
- If the set of
- Aggregate Queries to Count Contacts:
- An aggregate query counts the number of Contacts (
COUNT(Id)) for each Account inaccountIds. - The results are stored in a map (
contactsCount) for easy reference.
- An aggregate query counts the number of Contacts (
- Retrieve and Prepare Accounts for Update:
- The trigger queries all Accounts in
accountIds, retrieving their currentNumber_of_Contacts__cvalue. - It updates this field based on the data in
contactsCount. If an Account ID is not found in the map, the field is set to0.
- The trigger queries all Accounts in
- Collect Accounts for Update:
- Updated Account records are added to a list (
accountsToUpdate).
- Updated Account records are added to a list (
- Perform the Update Operation:
- The trigger updates all Accounts in the
accountsToUpdatelist to ensure theirNumber_of_Contacts__cfield is accurate.
- The trigger updates all Accounts in the
Sample Code :
Note – You can reuse this trigger on any objects which has a look-up relationship between parent and child.
Key Benefits:
- 🚀 Efficient: Uses aggregate queries to minimize the number of queries.
- 🎯 Accurate: Ensures the
Number_of_Contacts__cfield reflects real-time data. - 💪 Robust: Handles all DML scenarios, including null values and edge cases.
- 🔄 Real-Time Updates: Automatically syncs Contact changes to Account fields.
This trigger enhances data integrity, reduces manual intervention, and ensures Account records always display the correct contact count.
Thanks for reading……
For more helpful articles please visit – https://thesalesforcedev.wordpress.com


Leave a reply to Learning Apex Triggers (Part 2) – Welcome to The Salesforce Dev Cancel reply