How to write a basic APEX Trigger

Does this picture have anything directly to do with an APEX Trigger? Of course not. However, it does accurately depict the frustration I experienced the absolute first time I tried to write a Trigger.  (Bonus points if you have seen Bloodsport…)

The purpose of this article is to provide a declarative Admin (a.k.a “ButtonClickAdmin“) a decent primer to writing their first Trigger.  I do need to however go through the “declarative before programmatic” tenet – meaning that you always try to make something work through the Salesforce UI before going to a code / programmatic route.  A lot of triggers I’ve seen out there were written before a lot of the new cool features of Salesforce have been released – keep in mind these things:

  • Formulas
    • Salesforce provides you a rich relational pathing ability to grab fields of a Parent or Lookup simply by building it through a formula
  • Workflows
    • You can do Field Updates, Tasks, Emails, and Outbound Messages using Workflow
    • As of Spring ’12, you can now do “cross-object” Field Updates – before Spring ’12 a LOT of Triggers I saw existed just to do this (page 152 of the Spring ’12 Release Notes)
  • Validation Rules
    • Apart from the cross-object stuff, this is the other area where a lot of Triggers are written
      • Which can be OK if you have CRAZY complex computations to perform that you just can’t do with a V-Rule formula…
    • Use V-Rules to do your traditional data validation on fields

Salesforce does have some great documentation to get you started:

I’m going to pick and pull apart the documentation to give you an example of how I wrote a trigger just a while back to automatically add a Chatter post to a parent record when a child record was created.  You could really take this example and apply it to creating a record in any business case however.

First however, let’s dive into how a Trigger is structured…

Structure of a Trigger

trigger AddChatterPostToParent on ChildObject__c (after insert, after update) {

This is defining your trigger.  It’s stating that this is:

  1. a Trigger.
  2. “AddChatterPostToParent” is the name of this trigger
  3. “ChildObject__c” is the object that this trigger will be firing against
  4. The database operations that this trigger will fire on – your choices are “insert, update, delete, and undelete”
    • “before” = you have the ability to CHANGE values of fields
    • “after” = you do NOT have the ability to change values of fields
    • Great post from Salesforce on the pros vs. cons on before/after HERE

When I’m typically writing triggers, I like to put some comments at the beginning to describe what I’m trying to accomplish:

trigger AddChatterPostToParent on ChildObject__c (after insert, after update) {

// This trigger creates a Chatter Feed item for the parent record
// when a child record is created
// Created 20120718 Andy Boettcher
// Modified 20120718



Resources Available to You

When writing a trigger, you have a few objects already ready for you to use:


  • “” – this is a collection of the new records you are working with.
  • “trigger.newMap” – this is an indexed collection (map) of the new records you are working with.
  • “trigger.old” – this is a collection of the OLD values of the records you are working with, such as in the case of an update.
  • “trigger.oldMap” – this is an indexed collection (map) of the old records you are working with.

True/False Variables

  • “What kind of action am I working with?”
    • Trigger.isInsert
    • Trigger.isUpdate
    • Trigger.isDelete
    • Trigger.isUnDelete
  • “Is this a before or after action?”
    • Trigger.isBefore
    • Trigger.isAfter

// Run this code if we’re dealing with an Insert only
if(Trigger.isInsert) {
blah blah blah

// Run this code if we’re dealing with an Update only
if(Trigger.isUpdate) {
blah blah blah

// Run this code if we’re dealing with either an Insert or Update only
if(Trigger.isInsert || Trigger.isUpdate) {
blah blah blah


Here’s one of the biggest “gotchas” you’ll encounter working with APEX and Triggers – you are already definitely aware that Salesforce has “limits” on just about everything; Limits on objects, fields, data size, etc.  The same goes for APEX, but you have to account for it yourself in your code vs. having Salesforce nicely remind you when you’re near the threshold.  The official term is “bulkification” – meaning that our code has to be able to handle anywhere from a single record up to thousands without hitting a limit.  I will absolutely show and describe how we are dealing with this in the examples that follow.

Trigger Logic

The best way I can suggest bridging the concept of writing a formula / workflow in Salesforce and writing a Trigger is to “speak” what you want to do.  As you’re writing the Trigger, it’s very easy to get stuck on a tangent and over-code your solution.  Speak it, write it down, and then go through your code when you’re done to make sure you didn’t get off track.

  • “On all records coming through my trigger, I want to create a Chatter Post on the parent object.” (this is our example)
  • “On only the records with a value of “Tuesday” on the “Day Of Week” field, I want to create a new record in the “X” object.”

Putting the Trigger Together

trigger AddChatterPostToParent on ChildObject__c (after insert, after update) {

// This trigger creates a Chatter Feed item for the parent record
// when a child record is created
// Created 20120718 Andy Boettcher
// Modified 20120718

// Create Empty List to hold new items (bulkification)
List<FeedItem> lstFeeds = new List<FeedItem>();

// Loop through Comments and create Feeds
for(ChildObject__c c : {

FeedItem fi = new FeedItem();
fi.Type = ‘TextPost’;
fi.ParentId = c.ParentField__c;
fi.Body = ((Trigger.isInsert) ? ‘created’ : ‘updated’) + ‘ a Child Object on this Parent.’;



// Insert List if there are records contained within
if(lstFeeds.size() > 0) { insert lstFeeds; }


Those Pesky Unit Tests

With any APEX code, you need to write a Unit Test before you can deploy this new trigger to a Production environment.  Your Unit Test is meant to basically emulate how your code would be executed, and is structured to test if your desired result is what happens to come out of it.

To create a Unit Test for this Trigger, we need to create a Class that creates a Parent Object first, then creates a Child Object related to the Parent.  To be 100% kosher, we need to then update the new Child Object to cover both sides of the “if” condition for the Chatter Post body.

private class AddChatterPostToParent_UnitTest {

static testMethod void testTrigger() {

// Create Parent Object
ParentObject__c p = new ParentObject__c();
p.Name = ‘Test Parent’;

insert p;

// Tell Salesforce that we are starting our test now

ChildObject__c c = new ChildObject__c();

// Relate this Child to its Parent from the inserted record above
c.ParentId = p.Id;

c.Name = ‘Test Child’;

// Insert Child Record
insert c;

// Update Child Record
update c;

// Tell Salesforce we’re done with our test


Writing your first Trigger is kind of like jumping into the deep end of the pool with a lead weight belt, but that’s what your Sandbox is for.  Tinker, learn, ask questions…leverage the community.  You’ll get it.  =)

Transition from MSSQL to

I saw an excellent question on the #askForce Twitter feed from @corycowgill today that was “Besides standard Dev Guide, anyone know good blogs / materials to ramp up a DBA on”

I thought, “well heck, I’m an old school Microsoft VB/.NET/MSSQL programmer and I definitely had some ramp-up when transitioning to the platform.”  I figured I’d have a stab at it – trying to explain what I ran into in hopefully simple english.  =)

Step 1:  Let’s get some common footing.  Name, rank, and serial number soldier!

Let’s tackle the basics first…tables, fields, stored procs, triggers….what are they called in

  • Table = Standard and Custom sObject
  • Field = Standard and Custom Field
  • Relationship = Master/Detail and Lookups
  • Programmatibility (stored procs and triggers) = Workflows and APEX (classes and triggers)
  • Index = yes, but not what you’re used to…
  • View = not available in


Naming Convention.

  • “Label” vs “API Name”
    • Label is what your users will see that sObject or field as in the interface
    • API Name is what you will reference that sObject or field as in APEX
  • “__c” – this is a suffix you will see appended to the “API Name” of all custom sObjects and fields you create


You have a collection of sObjects called “standard sObjects”.  These are objects that are pre-built into your instance and cannot be deleted.  They are primarily under control by Salesforce (fields can be added as a result of a maintenance release).  You can add your own fields (custom fields) to **MOST** standard sObjects.  The “custom sObject” is a table that you create – fields, security, relationships, etc.  Standard and custom sObjects all live in the same partition – you can access both standard and custom objects from each other.

Examples of standard sObjects = Account, Contact, Event, Task, Opportunity, Campaign, Case.

Examples of custom sObjects = MyObject__c, YourObject__c, YourMom__c.

For sObjects, depending on the Edition you are subscribed to, you can have between 5 and 2,000 custom sObjects.


Just as you have standard and custom sObjects, you have the same with fields.  Standard fields will have names such as “FirstName, LastName, MailingAddress”, where custom fields will have “MyField1__c, MyField2__c, etc”.  Just as with MSSQL, you have the option of defining the data type for a field (I won’t go into all of them, see this link for details).

For fields, depending on the Edition you are subscribed to, you can have between 5 and 800 custom fields per object.

Relationships. has two kinds of table relationships:

  • Master-Detail (1:n) – allows a master object to control behaviors of a child object (security model, cascading actions, etc)
  • Lookup (1:n) – links two objects together, but has no bearing on security and the option of cascade actions

You can indeed to many-many (n:n) relationships in using either of the above relationship types above very similar to how you would use a junction table in MSSQL.

For relationships, you can define up to TWO Master-Detail and FIVE Lookup relationships per sObject.


Oh man – this is the biggest spot where I really miss the features of enterprise DBMSs like MSSQL.  There are no stored procs or triggers at the DB level, at least to how you’re used to thinking about them. does provide nearly all of the functionality that you’d normally tap via stored procs and triggers, but you have to dive into Workflows (declarative) and APEX classes / triggers (programmatic).

Before you freak out too much – bottom line is YES, between Workflow and APEX, you’ll be able to “proc” away.

In the interest of keeping on task here, I’m not going to dive into APEX on this post – if you want more info, just leave me a comment or hit me on Twitter (@andyboettcher).


This is double-edged sword – I both do and don’t miss being able to index any field.  I was pretty good at optimizing my indexes, but I knew a lot of DBAs who just sucked at it. does not do indexing as you’re used to.  There are indexes on certain fields by default, such as:

  • System Time Fields
  • Id
  • Name
  • Any relationship fields
  • Standard sObject-specific
    • Account:  Account Name, Account Owner, Account Record Type, Parent Account
    • Lead:  Company, Email, Lead Owner, Name
    • Contact:  Account Name, Contact Owner, Email, Name, Reports To

Depending on your schema’s needs, you can also contact Salesforce Support if you need indexes on other fields.  I haven’t done this personally, but everyone I have heard of that has done it has been successful (after having a valid and documented use case)

Step 2:  How do I create my schema?  Where’s my trusty Enterprise Manager / Management Studio?

The most raw and fully-functional place you can go is into Setup.

  • Standard Objects:
    • Setup / Customize / (find your object)
    • Fields are located as Setup menu options under each standard sObject
  • Custom Objects:
    • Setup / Create / Objects
    • Fields are located in the “Custom Fields” section on each custom sObject’s configuration page

If you’re feeling really spunky, Salesforce released the read/write “Schema Browser” with Summer ’12 (finally!) that is pretty darned cool.  It’s the closest you’re going to get to an ERD without going to the AppExchange too.

Step 3:  What tips and tricks should I keep in mind while building my Schema?

For the love of everything holy, remember to NORMALIZE!  The double-edged sword of is that it’s incredibly easy to create sObjects and fields.  Too easy.  Many an instance I’ve walked into with 400 fields in objects that could have been far more properly been done via normalization.  =)

Create a Naming Convention. has many examples of how they’ve approached naming conventions (just look through their online documentation or examine their standard sObjects).  Pick one and stick with it.

Along the normalization  lines – think long term and be as generic with field names (as appropriate).  Just because you can maintain seperate “Label” and “API” sObject and field names doesn’t mean you should make a habit of it.  Very little is more frustrating than having to hunt through your schema for a field with two names.

That’s a pretty good start.

Just as with MSSQL or any other DBMS for that matter – your schema is your foundation.  If you have a bad schema, you’re going to have a less-than-optimal application.  Be calm, deliberate, and thorough.  One big thing I try to impart on everyone I talk to about this is just because is quick and easy – that is no reason to execute that way.  A great saying I heard growing up from my dad while he and I would work on projects around the house – measure twice, cut once.

Questions?  Hit me up in the comments below or on Twitter (@andyboettcher).  Thanks for reading!!

Wrapper (or Helper) Classes – What can I do with them?

Wrapper Classes (I’ll refer to them in here as “WCs”) are a wonderful tool for so many things, but are mostly unknown or under-utilized by a lot of SFDC developers that I’ve met.  Recently on #askForce someone said they were looking for a good article on how WCs can be used without immediately diving into technical specs or the deep nitty-gritties but was unable to find anything, so I said CHALLENGE ACCEPTED!

The name “Wrapper Class” is exactly that.  It’s essentially an object that you can “wrap” data within.  Easy analogy to the real world?  Go buy a coffee maker at Sears.  The box it comes in?  That’s a wrapper class.  You take 50 of those coffee maker boxes on a shipping palette, (back to Salesforce lingo) you have a List<wrapperClass>.

I love WCs.  I would estimate that 80% of my overall projects utilize WCs in one way or another.  My primary use case for them is when I am creating interactive / rich grids of data.

What do I mean?

Typically when displaying a list of data, you create a GETer or a public List<whatever> variable and stick it in a datatable / repeat / etc.  That method totally works, but it’s pretty flat and without some additional wizardry via VF pretty non-functional.  (display-only)

What if I need to render a checkbox, picklist, or some other control / data point that isn’t necessarily on the record natively?  I don’t want to have to go and create a bunch of sObject fields just to tell whether or not I’ve put a checkmark in a box or if certain fields are filled out to render a section.

Enter WCs.

Code Example:  (I take no responsibility for the accuracy of my pseudo-code…Wordpress isn’t an IDE!)

Here’s a standard List<Account> implementation…

List<Account> lstAccounts = [SELECT Id, Name, Field1__c, Field2__c FROM Account WHERE some_field__c = ‘some value’];

<apex:pageBlockTable value=”{!lstAccounts}” var=”a”>
<apex:column headerValue=”Id” value=”{!a.Id}” />

That totally works and is a valid use case – but let’s get a little fancier.  Let’s throw in a checkbox column and an OutputPanel based on a Boolean value.  My use case here is that I want to have a list of records with checkboxes, and then through a CommandButton perform some sort of action only on the “checked” ones.  Sound similar to a multi-select list view in Salesforce now?  Yup.

First off, we need to think about what we want to put in the box (if you just went out and made a box…how would you know your contents would fit??).  Keeping with our use case, I would say that:

  • I want to have an sObject record
  • I want to have a Boolean value to tell me if it’s “checked” or not

Let’s first create our WC:

public class hClsAccount {

// declare variables just like a grown-up class!
public Account acct {get;set;}
public Boolean bolChecked {get;set;}

// constructor, again just like a grown-up class.
public hClsAccount(Account passAccountRecord) {

// Set initial variables
acct = passAccountRecord;
bolChecked = false;


With that created, we could just create a GETer of a List<hClsAccount> and display that on our page, but what fun would that be?  We couldn’t go back and run through it just using a GETer.  What I usually do is declare a List<helperClass> at the top of my parent class.

List<hClsAccount> lstAccounts {get;set;}

Within a method (or constructor, VF action, etc) you can fill this list.  Putting the sObject record in the WC constructor is just a script line-saving measure – you don’t have to.  The end result of this method is a fully populated list that you can now reference in VF.

public void fillHelperClass {

// Re-Instantiate List
lstAccounts = new List<hClsAccount>();

// Run your sObject query
for(Account a : [SELECT Id, Name, Field1__c, Field2__c FROM Account WHERE some_field__c = ‘some value’]) {

// Instantiate Wrapper Class
hClsAccount clsA = new hClsAccount(a);

Now, over to VF.  You’ll note that normally when accessing a List<sObject> in an apex:pageBlockTable, you refer to fields in the table as <var>.<field>.  With a wrapper class, you now have another layer in here – the object WITHIN the WC.  Looking above to our WC, to get the “Account Name” field, instead of “{!a.Name}” like you would normally, you’d do “{!a.acct.Name}” – “a” = your PBT var, “acct” = the sObject WITHIN the WC, and then “Name” = the field in the sObject.

<apex:pageBlockTable value=”{!lstAccounts} var=”a”>

<apex:column headerValue=”Do Something?”>
<apex:inputCheckbox value=”{!a.bolChecked}”

<apex:column headerValue=”Name” value=”{!a.acct.Name}” />

<apex:column headerValue=”Field 1″ value=”{!a.acct.Field1__c}” />

<apex:column headerValue=”Field 2″ value=”{!a.acct.Field2__c}” />


Looking pretty slick eh?  Yeah.  =)

Now – how to process those records you’ve checked…

public void processCheckedRecords() {

for(hClsAccount h : lstAccounts) {

if(h.bolChecked) {
// Do your logic.
String strAccountName = h.Acct.Name;



What’s next?  Really anything you can think of!  Picklists, boolean logic to render/not render columns, heck…even CSS if you are feeling “violate-y of the MVC”.  You can even have methods IN your WC to do certain things just as you’d do in your parent class.  Pretty slick.  =)

Seems pretty easy reading a blog – go ahead and try it out, give me a shout if you have questions.  (Twitter, comment below, whatever.)

Salesforce Update Field without Query

I had someone call me today and ask about this – and I realized I haven’t shared this neat little nugget of knowledge on here yet.

Business case – I’m looping through stuff and I just need to update a value on another related record for some reason.  On the record I’m looping through, I have the Id of that related record (Lookup, WhoId, WhatId, OwnerId…whatever) – and my usual M.O. is to run an initial loop of my records, pull those Ids into a Set and the SOQL up a List<whatever>, and then just deal with it in the subsequent logic loop.

Totally works – but in the eternal pursuit of streamlining code to stay within the governor limits, I stumbled across this little gem:

Instead of running that initial SOQL query to build the list of related objects to update, you can do a neat little UPSERT (or UPDATE if you like) on a “new” object:

(Using a before-triggered Contact action – trying to update an Account field for this example)

List<Account> lstAccountsToUpdate = new List<Account>();
for(Contact c : {
// Regular Contact Logic (yes, it's pseudo-code)
if blah blah = etc etc, c.AddError(whatever);
// Update Account Object - pass the AccountId from the Contact object into the new object
Account accUpdate = new Account(Id=c.AccountId) 
accUpdate.Field_I_Want_To_Update__c = 'whatever';
if(lstAccountsToUpdate.size() > 0) { upsert lstAccountsToUpdate; }

And there ya be – one less SOQL query you have to make.

Taking Notes – Cloud Application

I’m an avid note taker.  On my shelf at home, you’ll find dozens of 100% used notebooks full of notes from business meetings, community events, volunteering, etc.  I would haul these things around but often would have inevitably forgotten the one notebook I needed at home.

Enter Evernote.

Man I love this app.  I have it installed on my work laptop, home computer, Android Phone, and iPad.  (The basic edition is free – you only need to purchase a subscription if you want to start sharing / collaborating on notes with other people.)

No matter where I go – Evernote keeps all of my notes centralized and synchronized between all devices all the time.  Even if I don’t have Internet access at the time, I can view all of my notes, make changes, and next time I’m online the changes will just sync up in the background.

Oh man – what a difference one app makes, and another shining example of how awesome properly thought-out cloud utility apps are.  NICE.