Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the user-registration
domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init
action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/functions.php on line 6121
Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the hashone
domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init
action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/functions.php on line 6121
Warning: Cannot modify header information - headers already sent by (output started at /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/functions.php:6121) in /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/rest-api/class-wp-rest-server.php on line 1896
Warning: Cannot modify header information - headers already sent by (output started at /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/functions.php:6121) in /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/rest-api/class-wp-rest-server.php on line 1896
Warning: Cannot modify header information - headers already sent by (output started at /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/functions.php:6121) in /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/rest-api/class-wp-rest-server.php on line 1896
Warning: Cannot modify header information - headers already sent by (output started at /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/functions.php:6121) in /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/rest-api/class-wp-rest-server.php on line 1896
Warning: Cannot modify header information - headers already sent by (output started at /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/functions.php:6121) in /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/rest-api/class-wp-rest-server.php on line 1896
Warning: Cannot modify header information - headers already sent by (output started at /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/functions.php:6121) in /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/rest-api/class-wp-rest-server.php on line 1896
Warning: Cannot modify header information - headers already sent by (output started at /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/functions.php:6121) in /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/rest-api/class-wp-rest-server.php on line 1896
Warning: Cannot modify header information - headers already sent by (output started at /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/functions.php:6121) in /customers/c/c/d/ccloudonline.nl/httpd.www/wp-includes/rest-api/class-wp-rest-server.php on line 1896
{"id":681,"date":"2017-03-13T13:37:21","date_gmt":"2017-03-13T13:37:21","guid":{"rendered":"http:\/\/ccloudonline.nl\/a-homepage-section\/?page_id=681"},"modified":"2020-01-13T17:53:45","modified_gmt":"2020-01-13T17:53:45","slug":"trigger-handler-to-rule-all","status":"publish","type":"page","link":"http:\/\/ccloudonline.nl\/?page_id=681","title":{"rendered":"Trigger Handler to rule ALL!"},"content":{"rendered":"
I want to share my ideas on this subject because it looks like there are plenty of flavors from where to pick up your designs and no all are going in the same direction. The first question I can think of.
\nDo we really need a Trigger Handler or Dispatcher or whoever you want to call it?
\nFor me, the answer is YES!, we do.<\/p>\n
It is not only that we need it but it is probably the first piece of code that should hit your environments. Yes, the first thing you should consider is to have a decent trigger structure that will make your domain layer a happy camper right from the start. <\/p>\n
People argue that “we really don’t need a Trigger Handler at the early stages<\/em>” because “we are still a small org<\/em>“, “the org will never need more than a few triggers, it is not going to be very active<\/em>“, and stuff like that. To be honest, I feel that thinking like that will not be the best approach. Right there you are probably making the first bad decision. There are plenty of books talking about this subject and all of them will conclude that you need this type of architectural designs in your org to have some kind of control over your triggers. As OOP is concerned, to have a trigger handler is a very logical and practical component. The most relevant and important fact is that “when you have more than one trigger of the same type, you cannot predict the order of execution<\/em> “, yes, you can’t ever predict which of those triggers is going to fire first, scary stuff.<\/p>\n For me, that is without any doubt a good reason to make sure I have something in place for my clients. A trigger handler will help me to control these scenarios and reduce any data inconsistency as much as possible. And there is more to think about, but this is already a pretty serious matter.<\/p>\n A lot of the triggers I have seen out there are not following best practices and common reason. The reality is that developers are pushed to write code at a fast pace with short deadlines and limited time to deliver their solutions. That is also the reason why you can find code that is not written following “best practices<\/em>” techniques.<\/p>\n To point out one more important issues, triggers run on system content mode! .. so for you to be able to control this you will need to create helper classes anyway. Triggers should contain as less code as possible. Triggers should be like bridges unifying code rather than executing complex code logics. And there are more, not @future methods will be allowed, no asynchronous calls and many other restrictions. Yes, you can build helper classes to avoid those restrictions, that is exactly the point.<\/p>\n If you are an architect or have been reading about salesforce architectural designs, you probably know something about the Domain Layer. This layer intends to ensure the behavior in which Apex Triggers are invoked, among other things. Based on OPP principals a trigger handler will enrich our code making our Separation of Concepts more solid and at the same time allowing us to reuse our code. So it is not crazy to say that a good trigger structure will make overall infrastructure more OOP friendly.<\/p>\n So let’s take an example to illustrate what I am saying here.<\/p>\n Let’s say we have a Custom Object, Quote__c. This object has a relationship of one-to-many to opportunities. So, one opportunity can have many Quote__c records. This custom object contains a custom field, Status__c. In contains more than this field but for the sake of this test lets just focus on this one. You could use the Process Builder for this operation, but again, for the sake of this test lets be nice. Trigger:<\/p>\n [code lang=”PHP”] \/\/Now we are going to fetch the Quotes__c records from those Opportunities in oppIds if(!theQuotes.isEmpty() &amp;amp;&amp;amp; theQuotes.size()&amp;gt;0) }catch(DMLException e){ This trigger is fine and it should work and we can just go on with our lives.<\/p>\n But what happens if time pass by and we realized that our org has increased in the number of triggers and we have more than one ‘after update’ trigger affecting our Quote__c object. But is not only the Quote__c object that is depending on triggers now, many other objects are also using triggers for different business processes with DML operations. So we could start thinking about the possible scenario in which data consistency can be negatively affected by this new situation. If we had our trigger handler in place right from the start we shouldn’t be concerned about what to do now because we built things on top of our architectural design and things are flowing as they should.<\/p>\n As much as I want to make a drama of this situation the reality is that is not, at least not yet. In organizations that are growing slowly, you could easily rectify the situation without not harm done. The true is that in many cases the problem grows and managers don’t want to lose time and\/or resources in fixing what they thing ‘ain’t broke’, bad manager.<\/p>\n The true is also that decisions like this are not taken seriously until the smelling organic material has hit the fan, then, and only then they realized the important amount of time, resources, and the most painful one, money they need to allocate to fix something that could have been easily avoided by building a trigger handler.<\/p>\n
\nWe want to delete all those Quotes records from any Opportunity if the Accept one Quote. It one Quote change the status to “Accepted” all other, not – accepted quotes, need to be sent to a better place, recycle bin in this case.<\/p>\n
\n\/\/Trigger initial lines
\ntrigger deleteQuotes on Opportunities(after update) {
\n Set&amp;lt;Id&amp;gt; oppIds = new Set&amp;lt;Id&amp;gt;();
\n for(Opportunity op: trigger.new)
\n {
\n oppIds.add(op.id);
\n }<\/p>\n
\n List&amp;lt;Quote__c&amp;gt; theQuotes = [SELECT Id FROM Quote__c WHERE Opportunities__c IN: oppIds AND Status__c !=’Accepted’]; <\/p>\n
\n {
\n try{
\n delete theQuotes; <\/p>\n
\n System.debug(‘ERROR:’ + e);
\n }
\n}
\n[\/code]<\/p>\n