You found this blog! Congrats! That must mean this is the first thing that you have searched for relating to Salesforce, or more likely, you have done some googling around about how to write a Trigger. Well, you’re in luck.
My google-fu is pretty good, and I do quite a bit of it searching around for best practices and how-to’s. It bothers me that I see so many helpful folks recommend ways of writing code that I don’t necessarily agree with. So, I wanted to create a best practices guide for writing triggers that I think are easy to understand, but also are just good ideas. I hope this list expands over time as I think of things (or people disagree with me enough to warrant an update).
A few rules that we will get into the details below:
- Only one Trigger per object
- Keep your logic out of the Trigger
- Bulkify everything!
- Self-document your code
One Trigger per Object
This is pretty self-explanatory, I think, but I have ran across too many orgs that have many Triggers created on a single object. I hope this blog finds a new developer somewhere and they are asking “Why would you only create one Trigger per object?”. What a great question!
There are quite a few reasons not to have multiple Triggers per object, but one of the biggest is upkeep. If you have multiple files to upkeep, it’s going to take you forever to, well upkeep it! Not to mention deploying it or god forbid refactor it. Yikes. Doesn’t that sound like a nightmare? Yes. The answer is yes.
So here’s the rule developers. One Trigger per object. Just like Oprah, you (Account) get a Trigger, you (Contact) get a Trigger, you (Case) get a Trigger! Everybody gets (one) Trigger!
You can thank me later.
Keep your logic out of the Trigger
This rule seems to have about 50% adoption across the community. Many folks love adding their logic in their Triggers. Many, including myself, do not. In the Salesforce recommended Trigger pattern, each Object has one Trigger. Each Trigger has one Class. If you have more than one Class on a Trigger, those Classes better be HUGE.
Here’s an example of a nice looking Trigger:
And the related Class:
There is a test to go along with the Class, but let’s talk about Tests on a different day.
This may look a bit confusing, but I’ll explain the structure. The trigger contains all of the events (before update, before insert, after update, etc). We reference those updates in our class in individual methods for each event (onBeforeInsert, onAfterInsert, etc). Then within those methods, we reference the real methods that are actually doing the work such as setPrimaryCampaignSource and oppUpdateSalesTeam which all have their own code in their own methods (not shown here).
What you have done here is separate the event from the logic, making it extremely easy to maintain and compartmentalize. We also took it a step further and separated the logic from the action. Some might say this is too complicated. Maybe, it’s possible. I much prefer this approach to having extremely messy code that is not easily readable and scalable.
I have interviewed my fare share of Salesforce developers ranging from junior developers just out of College to those who have been developing on Salesforce since you could write code on Salesforce. My favorite question to ask in these interviews is to write an extremely simple Trigger that updates a field on Account or Contact. It is painful to watch folks attempt to write this sudo code on a whiteboard .
Before you interview with me, read up on Bulkification. Here’s a quick example of a non-Bulkified update:
We are looping through a grouping of Cases and updating the Status to a value of ‘Closed’. Then within the same loop, we are updating each case.
Now that same update Bulkified:
We are doing virtually the same thing, except waiting until the loop is finished before updating the Cases. And we made an improvement by updating the Cases all at the same time instead of one by one.
The problem you’re going to run into in creating non-Bulkified code is that many times, things in Salesforce don’t just happen one at a time. What if we dataload some of this data? For a few hundred rows that’s pretty fast. But let’s say we need 100k or 500k. This Trigger is going to execute one at a time, making your dataload last forever, and eventually timing out/fail. If you were to Bulkify the code, you can do just about anything at any time and the code will handle the data at any scale.
I would be remiss to not mention that there are some times where Bulkification is not completely possible. In these rare examples, I urge you to try to refactor your code or process to be able to be run in Bulk. If not, you are going to limit future productivity that undoubtedly will expand upon the functionality you have created. Over time it will come back to haunt you and you’re going to pay some consultants to come in and fix this down the road.
Self-document your code!
In our org, we try to add comments where appropriate to everything. I don’t think we overdo it, and in fact, I really appreciate the level of detail we have. In my years as a consultant, it became very important to know who did what in a piece of code so we could try to see if we were going to be breaking anything, or review a change log in the code to see who broke the deployment.
Those of you using Continuous Integration may not have use for this as things like Github and Bitbucket have built in source comments and change logs. But, let’s say you don’t have that, or you want to propose a process for the developers at your company who are making changes to files that you may not have complete insight into.
Above every Class, we have an identification section, as well as above each Trigger, Visualforce page and Component. We also try to identify each method with a section as well. The standard we use is as follows:
<br />/*------------------------------------------------------------ Author: Mark Passovoy Company: WatchGuard Description: Helper for xyz page Inputs: none History: 11/29/16 Mark Passovoy Created 11/30/16 Kevin Johnson Added a new method to query Contacts ------------------------------------------------------------*/
The information available here gives some context to what is going on, so someone who many not be completely familiar with the code or codebase can get a quick snapshot of what is going on in a Class, Method, Page or Component. Granted the commenting of the section will be a bit different in a Page and Component but the general principal applies. Shoutout to Ray Dehler who I believe exposed me to this extremely helpful practice.
When someone makes a change to this code, they will add a new line under the history section, documenting the date, their name and the change that was made to the code. This becomes invaluable for teams using a shared environment.
There it is. The 4 rules to be successful in writing a Trigger. Now all you need to do is learn to write the code!