14

I have a general best practices question about triggers. I have created a handful of triggers that perform different actions but are called by the same event, such as after account update/insert/delete.

Is it best to keep those triggers separate and name them accordingly (i.e. UpdateMyCustomFieldOnAccountUpdate)? Or, is it best to have a general 'AccountTrigger' trigger that contains all the functions that should be performed on Account update/insert/delete? And by doing so, do you avoid recursive trigger execution?

Thank you in advance for any help.

1 Answer 1

14

It is general best practice to consolidate. The main advantage here is control of execution. When you have 2 triggers on the account object, there is no way to know or control which fires first. If however, you move those triggers into a utility class, called by a single account trigger, you now can control the order in which they are fired.

2 Trigger approach

trigger AccountTrigger1 on Account (before insert){
     //your logic
}

trigger AccountTrigger2 on Account (before insert){
     //your otherlogic
}

When you insert an account, sometimes trigger1 will fire first, and sometimes trigger2 will fire first, there is no way to predict or control this.

Consolidated approach

trigger AccountTrigger1 on Account (before insert){

     AccountTriggerHelper helper = new AccountTriggerHelper();

     helper.myFirstMethod(trigger.new);
     helper.mySecondMethod(trigger.new);
}

public class AccountTriggerHelper {

     public void myFirstMethod(list<Account> accs) {
          //your logic
     }
     public void mySecondMethod(list<Account> accs) {
          //your logic
     }
}

So now you can see that you have control over the order of execution of your trigger logic.

You could just as easily change the order of execution by changing the order of method calls in your trigger like below

trigger AccountTrigger1 on Account (before insert){

     AccountTriggerHelper helper = new AccountTriggerHelper();

     helper.mySecondMethod(trigger.new);   //SWITCHED ORDER
     helper.myFirstMethod(trigger.new);
}

EDIT

To control recursion, you would still want to utilize static variables. I generally do this with another class. Something like this

public class TriggerContextUtility {

    private static boolean firstRun = true;

    public static boolean isFirstRun() {
        return firstRun;
    }

    public static void setFirstRunFalse(){
        firstRun = false;
    }
}

Then you would use this in your trigger like this

trigger AccountTrigger1 on Account (before insert){

     AccountTriggerHelper helper = new AccountTriggerHelper();
     If(TriggerContextUtility.isFirstRun()) {
          TriggerContextUtility.setFirstRunFalse();
          helper.myFirstMethod(trigger.new);
          helper.mySecondMethod(trigger.new);
     }
}
11
  • 1
    It will not inherently prevent it. You still need to use static variable to control recursion. Commented Jul 3, 2014 at 13:26
  • 2
    Do you see an advantage to using an instance of your trigger helper class, as opposed to setting up your methods as all static? Commented Jul 3, 2014 at 14:27
  • 2
    No, not really. You have a good point. could just as easily set them up as static. Actually probably makes more sense Commented Jul 3, 2014 at 14:31
  • 1
    The other good point of consolidation is governor limits; by combining queries into a single call, you can often reduce the overhead versus multiple calls. Many times it may not matter the precise order, but usually triggers in the same object need the same related records (usually parent), which you can consolidate.
    – sfdcfox
    Commented Jul 4, 2014 at 7:03
  • 1
    So I know everyone uses static variables to control trigger recursion, but this doesn't seem like the right approach. If for instance a downstream trigger action created another account the trigger wouldn't fire on it. At a minimum I'd advise using a set of ids for the records that have been processed, so in a second execution a new account is processed. Even better is caching the trigger.new values in a map by id, and using that instead of trigger.old, this is useful for when you're checking if a change has occurred. Commented Jul 8, 2014 at 21:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .