How to ByPass and Apex Triggers and Avoid Loops
Sometimes, when developing a trigger from some reasons we need to by pass the a trigger, may, as I mentioned in my previous post "System.LimitException: Too many SOQL queries: 101", sometimes we have loops in our triggers logic.
In Other occasions we just want to bypass because records were processed previously. Our first approach for bypassing its to execute an SOQL query to see if record need to be processed or use fields in the object.
But due to Salesforce Order of Execution or other conditions like loops in the code, the info from Database might not be recent. In this cases I have seen better results using static class to control the logic, something like:
The use this class in the trigger to mark records that were processed, depending on the logic we can use record Id, or any other field that makes sense. (remember that record wont have an Id in a Before Insert trigger, Id will be assigned after all before triggers ran).
Similarly we could modify the class to use the database in order pre-fill some values of records that were already processes. Of course we need to consider the governor limits of salesforce and use the helper class properly (EG: avoid an SOQL with more that 50k records, or the class will fail).
Sometimes, when developing a trigger from some reasons we need to by pass the a trigger, may, as I mentioned in my previous post "System.LimitException: Too many SOQL queries: 101", sometimes we have loops in our triggers logic.
In Other occasions we just want to bypass because records were processed previously. Our first approach for bypassing its to execute an SOQL query to see if record need to be processed or use fields in the object.
trigger TriggerTest on User (before insert. before update) { //First go to Database Setids = Trigger.newMap.keySet(); List relatedObjs = [SELECT Id,Name FROM relatedObject__c WHERE parent__c in :ids]; //Here check which users need to be processed. List UsersToProcess = new List (); for(User usr: Trigger.new){ //Use the values on relatedObjs to validate UsersToProcess.add(usr); } //Process the records if(UsersToProcess.size() > 0){ //Do the process logic, usually a helper class to perform a task } }
But due to Salesforce Order of Execution or other conditions like loops in the code, the info from Database might not be recent. In this cases I have seen better results using static class to control the logic, something like:
public class TriggerHelper { Private static SetbypassedUsers ; public static void generateSet(){ bypassedUsers = new Set (); //Here you can add more logic, like get some users from a custom object or with an specific detail } public static void addUserToByPass(String UserId){ if (bypassedUsers == null){ generateSet(); } bypassedUsers.add(UserId); } public static boolean doesUserNeedToBeByPassed(String UserId){ if (bypassedUsers == null){ generateSet(); } return bypassedUsers.contains(UserId); } }
The use this class in the trigger to mark records that were processed, depending on the logic we can use record Id, or any other field that makes sense. (remember that record wont have an Id in a Before Insert trigger, Id will be assigned after all before triggers ran).
trigger TriggerTest on User (before insert, before update) { ListThis model can be improved to add more complexity, instead of having an static set on the helper class, we could use an static Map and have more complex validations.UsersToProcess = new List (); //First check users to process. for(User usr: Trigger.new){ if( !TriggerHelper.doesUserNeedToBeByPassed(usr.UserName) ){ //Here usually add an if to only add those users that need to be processed. UsersToProcess.add(usr); } } //Process users if there is any if(UsersToProcess.size() > 0){ for(User usr: UsersToProcess){ //Do the process logic, ussually a helper class to perform a task TriggerHelper.addUserToByPass(usr.UserName); } } }
Similarly we could modify the class to use the database in order pre-fill some values of records that were already processes. Of course we need to consider the governor limits of salesforce and use the helper class properly (EG: avoid an SOQL with more that 50k records, or the class will fail).
Comments
Post a Comment