function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Vinod Kumar 92Vinod Kumar 92 

Child has Lookup relationship to parent, Count the number of child records on the each parent object

Count the number of child records on the each parent object, child has Lookup relationship to parent.
Take care that the trigger should follow one trigger per object architecture, should be bulkified and should have 90+% test code coverage.

Here Obj1: Parent__c
            Child_Count__c
     Obj: Child__c
            Parent__c -Lookup to parent

Note:.1 Implement below apex class, it has to work in all cases(insert,update,delete,undelete) and call the methods with the help of below trigger.
2. This code working gud except update functionality. So can any body check out and give me right code for update functionality ASAP. Thanks in advance.
         
   

Apex Class:

public class ChildCountHelper{
    
    //List<Parent__c> parentList = [select id, child_count__c, (select id from child__r) from Parent__c where id in :parentIDSet];
    
    public List<ID> conList= new List<ID>();
    
    public static void handleBeforeInsert(List<Child__c> childList){
        Set<ID> parentIDSet = new Set<ID>();
        
        for(Child__c childRec: childList){
     
            parentIDSet.add(childRec.Parent__c);
            
        }
        
        Map<ID, Parent__c> parentMap = new map<ID, parent__c>([select id, child_count__c from Parent__c where id in :parentIDSet]);
        for(Child__c childRec: childList){
            if(parentMap.get(childRec.Parent__c).child_count__c == null){
                parentMap.get(childRec.Parent__c).child_count__c = 0;
            }
            parentMap.get(childRec.Parent__c).child_count__c ++;
        }
        update parentMap.values();
    }
    
    public static void handleBeforeUpdate(List<Child__c> newChildList, List<Child__c> oldChildList){
        Set<ID> parentIDSet = new Set<ID>();
        Map<ID, ID> oldChildMap = new Map<ID, ID>();
        
        for(Child__c childRec: newChildList){
            parentIDSet.add(childRec.Parent__c);
        }
        
        for(Child__c childRec: oldChildList){
            parentIDSet.add(childRec.Parent__c);
            oldChildMap.put(childRec.Id, childRec.Parent__c);
        }
        
        Map<ID, Parent__c> parentMap = new map<ID, parent__c>([select id, child_count__c from Parent__c where id in :parentIDSet]);
        for(Child__c childRec: newChildList)
       {
        /*if(ChildRec.Parent__c!=null){  */
            if(parentMap.get(childRec.Parent__c).child_count__c == null){
                parentMap.get(childRec.Parent__c).child_count__c = 0;
            }
           // }
            if(childRec.Parent__c != oldChildMap.get(childRec.id)){
                if(oldChildMap.get(childRec.id) == null && childRec.Parent__c != null){
                    parentMap.get(childRec.Parent__c).child_count__c ++;
                }else if(oldChildMap.get(childRec.id) != null && childRec.Parent__c == null){
                    parentMap.get(oldChildMap.get(childRec.id)).child_count__c --;
                }else if(oldChildMap.get(childRec.id) != null && childRec.Parent__c != null){
                    parentMap.get(oldChildMap.get(childRec.id)).child_count__c --;
                    parentMap.get(childRec.Parent__c).child_count__c ++;
                }
            }
            
        }
        update parentMap.values();
    }
    
    public static void handleBeforeDelete(List<Child__c> childList){
        Set<ID> parentIDSet = new Set<ID>();
        for(Child__c childRec: childList){
            parentIDSet.add(childRec.Parent__c);
        }
        
        Map<ID, Parent__c> parentMap = new map<ID, parent__c>([select id, child_count__c from Parent__c where id in :parentIDSet]);
        for(Child__c childRec: childList){
            if(parentMap.get(childRec.Parent__c).child_count__c == null){
                parentMap.get(childRec.Parent__c).child_count__c = 0;
            }
            parentMap.get(childRec.Parent__c).child_count__c --;
        }
        update parentMap.values();
    }
    
    public static void handleBeforeUnDelete(List<Child__c> childList){
        Set<ID> parentIDSet = new Set<ID>();
        for(Child__c childRec: childList){
            parentIDSet.add(childRec.Parent__c);
        }
        
        Map<ID, Parent__c> parentMap = new map<ID, parent__c>([select id, child_count__c from Parent__c where id in :parentIDSet]);
        for(Child__c childRec: childList){
            if(parentMap.get(childRec.Parent__c).child_count__c == null){
                parentMap.get(childRec.Parent__c).child_count__c = 0;
            }
            parentMap.get(childRec.Parent__c).child_count__c ++;
        }
        update parentMap.values();
    }

}


*****************************

//Trigger 1:


trigger ChildTrigger on Child__c (before insert, after update, after delete, after undelete) {
    if (Trigger.isInsert) {
        ChildCountHelper.handleBeforeInsert((List<Child__c>)Trigger.NEW);
    }else if (Trigger.isUpdate) {
        ChildCountHelper.handleBeforeUpdate((List<Child__c>)Trigger.NEW, (List<Child__c>)Trigger.OLD);
    }else if (Trigger.isDelete) {
        ChildCountHelper.handleBeforeDelete((List<Child__c>)Trigger.OLD);
    }else if (Trigger.isUndelete) {
        ChildCountHelper.handleBeforeUnDelete((List<Child__c>)Trigger.NEW);
    }
ManojjenaManojjena
Hi Vinod,
Try with below code ,
 
trigger ChildCount  on Child__c ( after insert,after delete,after undelete) {
     Set<Id> parentIdSet=new Set<Id>();
     List<Parent__c> parentListToUpdate=new List<Parent__c>();
    if(Trigger.isInsert ||Trigger.isUndelete){
        for(Child__c cld : Trigger.new){
            if(cld.Parent__c != null)
                parentIdSet.add(cld.Parent__c);     
        }
    }If(Trigger.isDelete){
       for(Child__c cld : Trigger.old){
            if(cld.Parent__c != null)
                parentIdSet.add(cld.Parent__c);     
        }
    }
   for(AggregateResult res : [SELECT count(Id)can,Parent__c FROM Child__c WHERE Parent__c IN :parentIdSet group by Parent__c]) {
          parentListToUpdate.add(new Parent__c(Id=(Id)res.get('Parent__c'),Child_Count__c=(Integer)res.get('can')));
    }
    try{
      update parentListToUpdate;
    }catch(DmlException de){
      System.debug(de);
    }
}

Let me know if it helps !!
Thanks
Mnaoj
Vinod Kumar 92Vinod Kumar 92
Hi Manoj,

          Thanks for giving reply. I'm also written a trigger, but here problem is i need to work on with above apex class. So please check out above code in that update functionality was not working. If u do the help means it will be appreciated. Thanks
ManojjenaManojjena
Hi Vinod ,

If you need handler class please try with belwo code .
Trigger code
trigger ChildCount  on Child__c ( after insert,after delete,after undelete) {
    if(Trigger.isInsert || Trigger.isUndelete){
		ChildCountHelper.handleAfterInstUnDel(trigger.new);
	  
	}If(Trigger.isDelete){
		ChildCountHelper.handleAfterDelete(trigger.old);
	}
}
Handlerclass
public class ChildCountHelper{
	public static void handleAfterDelete(List<Child__c> childList){
	    Set<Id> parentIdSet=new Set<Id>();
        for(Child__c cld :childList){
            if(cld.Parent__c != null)
                parentIdSet.add(cld.Parent__c);     
        }
		if(!parentIdSet.isEmpty()){
		   finalCountUpdate(parentIdSet);
		}
	}
	public static void handleAfterInstUnDel(List<Child__c> childList){
	    Set<Id> parentIdSet=new Set<Id>();
        for(Child__c cld : childList){
            if(cld.Parent__c != null)
                parentIdSet.add(cld.Parent__c);     
        }
		if(!parentIdSet.isEmpty()){
		   finalCountUpdate(parentIdSet);
		}
	}
	public Static void finalCountUpdate(Set<Id> idSet){
	    if(!idSet.isEmpty()){
			List<Parent__c> parentListToUpdate=new List<Parent__c>();
			for(AggregateResult res : [SELECT count(Id)can,Parent__c FROM Child__c WHERE Parent__c IN :parentIdSet group by Parent__c]) {
			  parentListToUpdate.add(new Parent__c(Id=(Id)res.get('Parent__c'),Child_Count__c=(Integer)res.get('can')));
			}
			try{
			  update parentListToUpdate;
			}catch(DmlException de){
			  System.debug(de);
			}
		}
	    
	}
}
Let me know if it helps !!
Thanks
Manoj
 
Vinod Kumar 92Vinod Kumar 92
Hi Manoj,

        Thanks for giving reply. i tried with above code, update functionality is not working. So if u have any changes in above code, pls check out and give me reply.. it would be great and appreciated u. Thank you
Vinod Kumar 92Vinod Kumar 92
Its very urgent.. i need helper class with trigger in that events (before insert, after update, after delete, after undelete) respectively. pls if any body sends the code it would be appreciated. Thanking you
ManojjenaManojjena
Hi Vinod,
I don't think record count wil increase or decrease on update .
Stil if you need please modify the trigger code like belwo .
 
trigger ChildCount  on Child__c ( after insert,after delete,after undelete,after update ) {
    if(Trigger.isInsert || Trigger.isUndelete || Trigger.isUpdate){
		ChildCountHelper.handleAfterInstUnDel(trigger.new);
	  
	}If(Trigger.isDelete){
		ChildCountHelper.handleAfterDelete(trigger.old);
	}
}

Thanks
Manoj

 
Vinod Kumar 92Vinod Kumar 92
Hi Manoj,

Thanks for spending ur valuable time and giving response. i used above updated code, then to count is not updating. I think we have to do modfications in apex class only. So if possible do it, it wil be great. Thank you.
ManojjenaManojjena
Whatis the error you are getting ??