Simplified Status Management in Apex Triggers

Have you ever found yourself needing to deactivate a trigger for maintenance activities on records or during a code deployment?

At a basic level, the process of activating/deactivating a trigger is straightforward. Navigate to your Salesforce sandbox, modify the trigger’s status, and deploy the code. Depending on the unit test coverage for the trigger, you may need to adjust the test class and include it in the deployment.

However, in Salesforce organizations with extensive code, the deployment process can be time-consuming, taking 20 minutes, 40 minutes, or even more.

What if you could easily toggle a box to turn a trigger on or off?

The solution I’m about to demonstrate simplifies and expedites trigger status manipulation using a Custom Setting. At its core, the trigger will check for its own status record in a Custom Setting object, and based on that designation, it will either process its logic or remain inactive.

To implement this solution, the first requirement is a Custom Setting object. Go to Setup > Develop > Custom Settings > New, and provide the following details:

  • Label: Trigger Status
  • Object Name: Trigger_Status
  • Setting Type: List
  • Visibility: Protected
  • Description: The triggers for the org and their active/inactive status.

Next, set up a custom field for this new object:

  • Field Label: Status
  • Field Name: Status
  • Data Type: Checkbox
  • Description:
  • Help Text: Checked means the trigger is active and will fire.
  • Default Value: Checked

Ensure that you create a corresponding trigger record in the Custom Setting object. Navigate to the Custom Setting object in Salesforce setup, click the Manage button, and then the New button:

  • Name: contactTrigger
  • Status__c: checked

Now, let’s create our trigger. In this example, we’ll use a Contact trigger and a trigger handler. The simplified trigger is as follows:

/*
	Created by: Greg Hacic
	Last Update: 30 July 2015 by Greg Hacic
	Questions?: greg@interactiveties.com
	
	Notes:
		- tests located at contactTriggerTest.class
*/
trigger contactTrigger on Contact(after insert) {
	
	contactTriggerHandler handler = new contactTriggerHandler(); //construct the trigger handler
	
	if (Trigger.IsInsert && Trigger.isAfter) { //after insert
		handler.OnAfterInsert(Trigger.new); //pass the new List of records to the handler for processing
	}

}

The handler will be where we grab the trigger status from the Custom Setting.

/*
	Created by: Greg Hacic
	Last Update: 30 July 2015 by Greg Hacic
	Questions?: greg@interactiveties.com
	
	Notes:
		- tests located at contactTriggerTest.class
*/
public class contactTriggerHandler {
	
	public void OnAfterInsert(List<Contact> newRecords) {
		if (isOkayToRun) { //if it is okay to run the trigger
			contactAfterInsertLogic(newRecords); //pass the List of new records to the contactAfterInsertLogic for processing
		}
	}
	
	//determines whether or not the trigger logic is okay to run
	public static Boolean isOkayToRun {
		//getter constructor
		get {
			Boolean returnBoolean = true; //default the boolean return value to true - this is done to make sure the trigger fires when the developer fails to create a corresponding Custom Setting record
			Trigger_Status__c t = Trigger_Status__c.getInstance('contactTrigger'); //grab the Trigger_Status__c custom setting object record named contactTrigger
			if (t != null) { //if there was a record found
				returnBoolean = t.Status__c; //set the returnBoolean value to the Status__c boolean value for the found record
			}
			return returnBoolean; //return the boolean value
		}
	}
	
	//method for processing of actual business logic related to the trigger
	private void contactAfterInsertLogic(List<Contact> newRecords) {
		for (Contact c : newRecords) { //for all records
			//do something here
		}
	}

}

As you can see we grab the trigger status from the Custom Setting when the trigger handler is constructed. Since the information is stored in a Custom Setting we can easily and efficiently access it using the isOkayToRun getter method.

Make sure you use the same Name from your Custom Setting on line 22 within the trigger handler. Otherwise, the handler will not find a matching record in the Custom Setting object.

Apex code is no good without unit tests…

/*
	Created by: Greg Hacic
	Last Update: 30 July 2015 by Greg Hacic
	Questions?: greg@interactiveties.com
	
	Notes:
		- tests contactTrigger.trigger (100.00% coverage)
		- tests contactTriggerHandler.class (100.00% coverage)
*/
@isTest
private class contactTriggerTest {
	
	//tests contactTrigger.trigger & contactTriggerHandler.class
	static testMethod void triggerLogic() {
		//create some Trigger_Status__c records
		List<Trigger_Status__c> triggerStatus = new List<Trigger_Status__c>();
		triggerStatus.add(new Trigger_Status__c(Name = 'contactTrigger', Status__c = true));
		insert triggerStatus;
		//create some accounts
		List<Account> accounts = new List<Account>();
		accounts.add(new Account(Name = 'Tess Is My Dog LLC'));
		insert accounts;
		Test.startTest(); //denote testing context
		//create a Contact
		List<Contact> contacts = new List<Contact>();
		contacts.add(new Contact(AccountId = accounts[0].Id, FirstName = 'Tess', LastName = 'Dachshund'));
		insert contacts;
		Test.stopTest();
	}

}

The potential time savings with this trigger configuration can be substantial. In scenarios where time is critical, having such a setup in your organization could prove to be highly beneficial.