Trigger: When Account Email get updated all related Contact Email Should get updated

Example: When Account Email get updated all related Contact Email Should get updated.

Solution

Solution 1: Handle single record.

trigger AccountTrigger on Account (before insert) {
    if(Trigger.isUpdate && Trigger.isAfter) { 
        List<Contact> allAssoContact = [Select Id, Email From Contact Where AccountId =: trigger.new limit 1];
     List<Contact> updateContact = new List<Contact>();
     for(Id accountId : Trigger.newMap.keySet()) { 
         if(trigger.oldMap.get(accountId).Email__c != Trigger.newMap.get(accountId).Email__c)  {
             Contact con = new Contact(Id=allAssoContact[0].Id);
             con.Email = trigger.oldMap.get(accountId).Email__c;
             updateContact.add(con);
         }
     }
     if(!updateContact.isEmpty()) { 
         update updateContact;
     }
 }
}

Problems in Solution 1

  • Wrong trigger event: the trigger is declared as before insert, but the code checks for isUpdate and isAfter. Those conditions are never true in a before insert trigger, so the code never runs. The trigger must be after update.
  • Only one Contact is updated: the query uses limit 1 and the code reads allAssoContact[0], so only the first Contact gets updated. An Account can have many Contacts.
  • Wrong email value: the code copies oldMap Email__c to the Contact. The Contact should receive the new value from newMap.
  • Not bulk-safe: the query matches all Contacts for the whole batch but only handles the first one.

Corrected solution (bulk-safe)

trigger AccountTrigger on Account (after update) {
    Map<Id, String> changedEmails = new Map<Id, String>();

    for (Account acc : Trigger.new) {
        if (acc.Email__c != Trigger.oldMap.get(acc.Id).Email__c) {
            changedEmails.put(acc.Id, acc.Email__c);
        }
    }

    if (!changedEmails.isEmpty()) {
        List<Contact> contactsToUpdate = new List<Contact>();
        for (Contact con : [
            SELECT Id, AccountId
            FROM Contact
            WHERE AccountId IN :changedEmails.keySet()
        ]) {
            con.Email = changedEmails.get(con.AccountId);
            contactsToUpdate.add(con);
        }
        update contactsToUpdate;
    }
}

How the corrected code works

  1. The trigger runs after update on Account. Email__c is the custom Email field on Account used in this example.
  2. The loop compares the old and new Email__c for each Account and stores only the changed ones in a Map of Account Id to new email.
  3. One query fetches all Contacts that belong to those Accounts.
  4. Each Contact gets the new email from the Map, and a single update saves them all.

How to test

  1. Create an Account with Email__c filled in and add three Contacts to it.
  2. Change the Email__c value on the Account and save.
  3. Open each Contact. All three should now show the new email.
  4. Save the Account again without changing Email__c. The Contacts should stay unchanged.

FAQ

Why use a Map?
The Map links each Account Id to its new email, so every Contact can look up the right value without extra queries.

Why after update and not before update?
We are changing Contact records, not the Account itself, so after update is fine and the Account is already saved.

Leave a Reply