The trigger must be authored on the Contact object. The following code functions for various operations:
- Inserting a Contact with an Account
- Updating/Switching Accounts on Contacts (updating count on both Accounts)
- Removing an Account from a Contact
- Deleting a Contact
- Undeleting a Contact
trigger ContactTrigger on Contact (after insert,after update, after delete, after undelete) { if(Trigger.isAfter) { Map<Id,List<Contact>> MapOfActIdandConList = new Map<Id,List<Contact>>(); List<Account> lstAct = new List<Account>(); Set<Id> AccountIdSetNew = new Set<Id>(); Set<Id> AccountIdSetOld = new Set<Id>(); if(Trigger.isInsert || Trigger.isUndelete || Trigger.isUpdate) { for(Contact contNew : Trigger.New) { if(contNew.AccountId != null) { AccountIdSetNew.add(contNew.AccountId); } } if(AccountIdSetNew.size()>0){ List<Contact> lstContNew = [Select Id,AccountId from Contact where AccountId in: AccountIdSetNew ]; for(Contact ct : lstContNew) { if(MapOfActIdandConList.containsKey(ct.AccountId)) { MapOfActIdandConList.get(ct.AccountId).add(ct); } else { MapOfActIdandConList.put(ct.AccountId, new List<Contact> {ct}); } } } } if(Trigger.isDelete || Trigger.IsUpdate) { for(Contact contOld : Trigger.Old) { if(contOld.AccountId != null) { AccountIdSetOld.add(contOld.AccountId); } } if(AccountIdSetOld.size()>0){ List<Contact> lstContOld = [Select Id,AccountId from Contact where AccountId in: AccountIdSetOld ]; for(Contact ct : lstContOld) { if(MapOfActIdandConList.containsKey(ct.AccountId)) { MapOfActIdandConList.get(ct.AccountId).add(ct); } else { MapOfActIdandConList.put(ct.AccountId, new List<Contact> {ct}); } } } } for( Id actId : MapOfActIdandConList.keySet()) { Account act = new Account(); act.Id = actId; act.Count_Contact__c = MapOfActIdandConList.get(actId).size(); lstAct.add(act); } if(lstAct.size()>0) { update lstAct; } } }