One of the things customers often ask is, “Why are you recommending that we should consolidate all the triggers on X object first?” and “Couldn’t you simply modify this trigger? They just work!” Our answer is that consolidating triggers is a best practice.
So then, why is it a best practice? One of the things we strive for at IC is understanding and providing the why. In fact, it’s so central to our culture, it’s Fundamental #1 in our IC Way.
Read on to learn why you should consolidate triggers, and what makes it a best practice.
One of the biggest reasons to consolidate triggers is to control the order of execution. If you have multiple triggers on the same object spread throughout your org, you have no guarantee in which order any of them are going to fire.
Why does controlling the order of execution matter?
Basically, it allows us to avoid unintended consequences. By consolidating triggers, we’re guaranteed to know in which order things are being processed and updated within our org. It allows for quicker troubleshooting of issues and quicker changes to business logic when needed.
One of the other major reasons to consolidate triggers is to control trigger recursion. In Salesforce, triggers are not guaranteed to fire only once. This could lead to unnecessary resource usage, roll-ups potentially firing multiple times, incorrect data entering your system, etc.. So why is this such a big deal?
Let me share a story from early in my Salesforce career to explain: In the first org I ever worked in, we had some consultants come in to help us add address verification to our org. A few months later, we were noticing that our allotment of API calls to our address verification service were disappearing at an alarming rate. As we investigated, we were shocked to learn that the initial developers did not take trigger recursion into consideration. So when a contact was being modified, it was making multiple calls to our verification service. It was wasting resources, and on top of it all, we then had to spend more developer time rewriting the triggers to take recursion into account.
1. Lower Code Maintenance Costs
Clean straight forward code like this is much easier to maintain and make additions to. Developers are expensive. When triggers are consolidated and the expected order of execution is clear, developers can get in and understand the triggers and make requested changes much faster.
2. Easier to Validate Business Rules
When triggers are consolidated and recursion is accounted for it makes it much easier to have a set of tests to ensure that your trigger automation is doing exactly what it’s supposed to.
3. Code Reuse
By following suggested trigger consolidation patterns it makes the code you write re-usable in other areas of your org. This could cut down on costs in the long run.
So now that we’ve talked about why you should consolidate triggers and the benefits of spending the extra time up front, how do we go about consolidating the triggers? Well there are a number of existing patterns you can follow. But we’ll outline a very simple one that Salesforce recommends.
First, if you’re changing existing extensive triggers I would recommend writing unit tests first that truly exercise your code. This will give you visibility to see where your triggers are failing and a route to validate that your trigger changes are working.
The simplest way to consolidate triggers is follow this pattern: A single trigger class per object. That trigger class in turn calls a helper class that handles all the business logic. Here is a brief example:
As you can see we’ve created a single trigger on Account. That trigger then in turn calls the AccountHelper class which will then handle any business logic that needs to be done. By creating the code this way, it allows us to change the order of logic by simply flipping which method gets called first. We can also see what is being done where and allows us to add any additional logic that may be needed. By following this pattern you can also reuse the AccountHelper in other parts of your org such as Visual Force Page controllers and Lightning Web components. This pattern does not inherently control recursion so we’ll need to add one more thing.
In order to control recursion we have to give the trigger some context to follow. This can be easily achieved by adding a third class to the mix that keeps track of whether the trigger has been run already. It would look something like this:
The example above is a bit heavy handed and will ensure that the business logic only runs once a transaction. But there are scenarios where you might need to run the trigger twice. For example, Account A is updated and the trigger runs on Account A. The first run flag is set to false and the business logic runs. Through a cascade of updates, Account B gets updated. Since the flag was set to false, Account B never gets the business logic run against it. So how do we account for this? With a small change instead of keeping track via a Boolean, we can track which records we processed and then only pass unprocessed records to our business logic. That code might look something like this:
Now that you understand why trigger consolidation is important, and you have a few ideas on how to consolidate your own triggers, take a minute to explore other IC Salesforce Developer insight articles, like “Tips for Building Salesforce Lightning Web Components”!