1

I need some suggestions in improving the 'prevent trigger' logic. I have parent 'Lead' object and couple of child objects. I have Trigger Helpers on each of these objects. When these child object records are inserted or updated, I need to update Lead but at the same time, I want to avoid firing the Trigger on Lead(We are doing this to stop firing Lead triggers when we don't need)

Object 1 Trigger:

trigger Object1Trigger on Object1(before update,before insert,after update, after insert) {

if(!Object1TriggerHelper.preventLeadTrigger() && !Object2TriggerHelper.preventLeadTrigger() &&
   !Object3TriggerHelper.preventLeadTrigger() && !Object4TriggerHelper.preventLeadTrigger())
{

//Do stuff
}

}

Object 1 Trigger Helper:

public with sharing Object1TriggerHelper{

private static boolean preventLeadTrigger = false;
 private static boolean preventObject1Trigger = false;

public static void insert_Object1(List<Object1> recordList)
{
 .....
 .....
  //DO Stuff
  preventLeadTrigger = TRUE;
  preventObject1Trigger = TRUE;
  update object1Records;
  update leadRecords;
  preventLeadTrigger = FALSE;
  preventObject1Trigger = FALSE:
}    

Similar code for Object 2,3 & 4

Lead Trigger:

trigger LeadTrigger on Lead(before update,before insert,after update, after insert) {

**//Is there a better approach than this i.e. creating static variable in each TH and then checking here**
if(!Object1TriggerHelper.preventLeadTrigger() && !Object2TriggerHelper.preventLeadTrigger() &&
   !Object3TriggerHelper.preventLeadTrigger() && !Object4TriggerHelper.preventLeadTrigger())
{

//Do stuff
}

}

Question: Instead of creating a staic boolean variable in each TH and then checking that in Lead Trigger, is there a better way?


@sfdcfox Thank you for your help. I used the above code and had one issue. When I call the disableTrigger method from my TH class and then check if the trigger is disabled by calling the isTriggerActive method, it returns FALSE which is working fine. But when I call the enableTrigger method and then check the status again, it is still returning FALSE. I made below changes to the enableTrigger & disable methods and it seems to be working fine. Can you please let me know your thoughts i.e my changes are OK or if I have missed something.

public static void enableTrigger(String name) {
        if(!current.enabled) {
            current.exceptions.add(name);
        }else
        {
            current.enabled = false;
            current.exceptions.add(name);
        }
    }
    public static void disableTrigger(String name) {
        if(current.enabled) {
            current.exceptions.add(name);
        }
        else
        {
            current.enabled = true;
            current.exceptions.add(name);
        }
    }

1 Answer 1

5

This is a simple version that I've used in a project in the past, as well as more complicated variants for particular needs. This class handles practically all use cases you can imagine.

In your trigger handler, you simply check if a trigger is enabled before running:

if(!TriggerUtils.isTriggerActive('AccountBeforeUpdate')) {
    return;
}
// Rest of logic here

To disable a specific trigger before you do updates, you can disable a specific trigger:

TriggerUtils.disableTrigger('AccountBeforeUpdate');
update accountRecordList;
TriggerUtils.enableTrigger('AccountBeforeUpdate');

If you're not sure a trigger has already been disabled, and you want to maintain that state before messing with the current state, you can do this as well:

TriggerUtils.saveState();
TriggerUtils.disableTrigger('AccountBeforeUpdate');
update accountRecordList;
TriggerUtils.restoreState();

This is also great for unit testing (e.g. disabling all triggers during @testSetup to improve performance).


TriggerUtils

public class TriggerUtils {
    Boolean enabled = true;
    Set<String> exceptions = new Set<String>();
    static TriggerUtils[] stack = new TriggerUtils[0];
    static TriggerUtils current = new TriggerUtils();

    public static void enableAll() {
        current.enabled = true;
        current.exceptions.clear();
    }
    public static void disableAll() {
        current.enabled = false;
        current.exceptions.clear();
    }
    public static void enableTrigger(String name) {
        if(!current.enabled) {
            current.exceptions.add(name);
        }
    }
    public static void disableTrigger(String name) {
        if(current.enabled) {
            current.exceptions.add(name);
        }
    }
    public static Boolean isTriggerActive(String name) {
        return current.enabled ^ current.exceptions.contains(name);
    }
    public static void saveState() {
        // Save current state to the stack
        if(stack.isEmpty()) {
            stack.add(current);
        } else {
            stack.add(0, current);
        }
        // Duplicate state
        TriggerUtils temp = new TriggerUtils();
        temp.enabled = current.enabled;
        temp.exceptions.addAll(current.exceptions);
        current = temp;
    }
    public static void restoreState() {
        if(!stack.isEmpty()) {
            current = stack.remove(0);
        }
    }
}
1
  • Hi @sfdcfox Thank You so much your help. Can you check my notes below. I could not add the entire thing in comments as it was too long.
    – Saha
    Commented May 25, 2019 at 0:16

You must log in to answer this question.

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