Triggers in Salesforce
Whenever you want to trap any Data Manipulation Operation (DML) on Salesforce sObject(Standard or Custom) and after trapping you want to perform any operation before and after a record is Inserted/Updated/Deleted from the force.com database. In this case we think about writing the triggers.
In triggers, two thing are really very important to understand one is action(insert/update/delete) and second is timings(before or after)
Note: Combination of action with timings known as events in triggers.
Events of Triggers:
- before insert
- before update
- before delete
- after insert
- after update
- after delete
- after undelete
Syntax:
Trigger <trigger name> on <Object name> (trigger Events) { // Implement the Logic here }
Trigger Context Variables
Context variables are used to access run-time context of an trigger. These types of variables are contained in the System.Trigger class.
Variables | Usage |
isExecuting | It returns true if the current context for the Apex is a trigger, not a Web service, a Visualforce(VF) page, or an executeanonymous() Application programming interface(API) call. |
isInsert | It returns true if this trigger got fired due to an insert action, from the Salesforce user interface, an API or , Apex, code. |
isUpdate | It returns true if this trigger got fired due to an update action, from the Salesforce user interface, the API or Apex code. |
isDelete | It returns true if this trigger got fired due to a delete action, from the Salesforce user interface, the API or Apex code. |
isBefore | It returns true if this trigger got fired before any record was saved in Salesforce. |
isAfter | It returns true if this trigger got fired after all records were saved in Salesforce. |
isUndelete | It returns true if this trigger got fired after a record is recovered from the Recycle Bin (i. e, after an undelete action from the Salesforce user interface, Apex, or the API.) |
New | It returns a list of new versions of the sObject records.
Note that this sObject list is only available in update and insert triggers, and also the records can only be modified in before triggers |
newMap | It returns a map of IDs to the new versions of the sObject records.
Note that this map is only available in before update, after update and after insert triggers. |
Old | It returns a list of the old versions of the sObject records.
Note that this sObject list is only available in delete and update triggers. |
oldMap | It return a map of IDs to the old versions of the sObject records.
Note that this map is only available in delete and update triggers. |
Size | The total number of records invoked in a trigger, both old and new. |
Bulkifying Triggers:
By default each and every trigger is a bulk trigger in nature which is used to process the multiple records at a time as a batch. For each batch of 200 records.
Best Practice of Triggers:
Trigger Best Practices: as per the best practice, we need to write one trigger per object and try to handle all the events from the same trigger and then call class from the same trigger based on the perform events.
- before insert
- after insert
- before update
- after update
- before delete
- after delete
- after undelete
So as per best practice, let us create one Trigger per object and let it handle all of the events that you need. Here is an example of a Trigger that implements all possible scenarios:
Example:
Let’s say we have a custom object called “Merchandise” in our org:
Scenario: We want to write logic on this object such that when a record of this object is deleted, we store the deleted record in a separate object called “Merchandise Archive”. That object definition is the same as the above object:
So let’s create an apex trigger on the Merchandise object by clicking the New button in the object’s schema page in Trigger section:
Now, here is the trigger code:
trigger ArchiveTrigger on Merchandise__c (before insert, after insert, before update, after update, before delete, after delete, after undelete) { if(Trigger.isDelete && Trigger.isAfter) { ArchiveMerchandise.archive(trigger.old); } /* if there is any other requirement of handling other event then simply use else if block and with the help of context variable handle that event and call other method of the class based on need and so on.*/ }
As we can see the trigger is called on the after delete event. The trigger is logic less i.e. we did not written any logic inside the trigger except just calling a handler class method ArchiveMerchandise.archive with required parameter.
Here is the code for the ArchiveMerchandise apex class:
public class ArchiveMerchandise { public static void archive (list rec) { list merch = new list (); for(Merchandise__c m : rec) { Merchandise_Archive__c archive = new Merchandise_Archive__c(); archive.name = m.name; archive.type__c = m.type__c; merch.add(archive); } insert merch; } }
Once we save this trigger and its activated, the trigger will create a new Merchandise Archive record every time whenever an existing Merchandise record got deleted.
Once the above record is deleted from Merchandise Object it will automatically create the ‘Merchandise Archive’ record, shown as below.