Droplets – Letting WFR’s update Lookup Fields

 In Salesforce

Here’s the challenge.  You’re a Salesforce administrator or developer and you need an easy, flexible way of setting the values of a field when circumstances demand it.

What’s your go to solution?  Probably Workflow Rules.  WFRs offer an easy, convenient and nearly foolproof means of accomplishing this that works in most circumstances.

One of the few situations where WFRs don’t work is when you’re trying to set the value of a field that relates objects.  These Lookup and Master-Detail fields are how you connect records to one another in Salesforce and WFR field-updates unfortunately won’t set their values.

Being Salesforce, though, there are multiple workarounds.

One of my favorites is an approach I call Droplets.  A droplet is a field that when you set it from within a WFR it acts as a surrogate for setting the lookup field.

Note:  This requires a little bit of code.  Yes, you’ll need to understand how to use sandboxes and deploy code, it’s apex after all, but still it’s not hard.

Overview:

  • Let’s say you have a custom object called myObject__c that relates to the Account object using the field AccountID__c; a lookup field.
  • Create a text field that’s a twin to the lookup field you want to be able to set.  In our example that might be called AccountID_Droplet__c that would be 18 characters long since Lookup fields store record IDs and Salesforce IDs are 15 or 18 characters.
  • Create a Before trigger on myObject__c, if you haven’t already, that passes the object’s records to the handler for processing.  Of course, we’ll bulkify it.
  • Create a trigger handler that loops through all of the myObject__c records it receives and does two quick things.
    • Copies the contents of the AccountID_Droplet__c into the AccountID__c field.
    • Clears out the contents of the AccountID_Droplet__c field so it’s ready for the next use.
  • Lastly, create a test method that exercises the code so you can deploy it.

Why go to all this work?  Now WFRs can be used to associate myObject__c records with Accounts by setting the droplet as a surrogate for the lookup.

Got it?  Now here’s the code:

Sample Trigger

trigger myObjectTrigger on myObject__c (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    if (trigger.isBefore && !trigger.isDelete){
        list<myObject__c> hasDroplets = new list<myObject__c>();
        for (myObject__c so : Trigger.new) {
            // of course we're bulkified
            if (so.AccountID_Droplet__c != null) hasDroplets.add(so);
        }
        myObject_Handler.processDroplets(hasDroplets);
    }
}

Sample Trigger Handler

public with sharing class myObjectTrigger_Handler {
    public static void processDroplets(list<myObject__c> hasDroplets){
        for (myObject__c has : hasDroplets) {
            has.AccountID__c = id.ValueOf(has.AccountID_Droplet__c); 
            has.AccountID_Droplet__c = null; 
        }
    }
}

Sample Test Code for the Trigger Handler

@isTest
private class myObjectTrigger_Handler_test {
    @isTest static void test_Droplets() {
        account a = new account(name='test account');
        insert a;
        myObject__c my = new myObject__c;
        my.AccountID_Droplet__c = string.ValueOf(a.id);
        insert my;
    }
}

Leave a Comment