sObjects: one weird little trick Trailhead doesn’t tell you
The Trailhead modules on “Apex Basics & Database” are – like most of the Trailhead modules – pretty fantastic but they do miss out one weird little trick: using sObjects as maps. This is another handy arrow in your ‘Dynamic DML’ quiver.
The “Manipulating Records with DML” unit has this code snippet:
// Create the account sObject
Account acct = new Account(Name='Acme', Phone='(415)555-1212', NumberOfEmployees=100);
// Insert the account by using DML
insert acct;
Line 2 is what we’re interested in. It uses a field name and the value that is going to be inserted into the field as key-value pairs like this:
Name=’Acme’
Phone='(415)555-1212′
NumberOfEmployees=100
There’s a clue here. What this means is we can treat an sObject like a map with the field name as the key and the value that is going to be inserted into the field as the value. Like this:
// Create the account sObject
Account acct = new Account();
acct.put('Name', 'Acme');
acct.put('Phone', '(415)555-1212');
acct.put('NumberOfEmployees', 100);
// Insert the account by using DML
insert acct;
}
Taking this one step further, you can create a utility method that takes a map consisting of field names and field values and creates an Account. Like so:
public static void createAccount(Map fieldValueMap) {
// Get the metadata so we can do some data type checking
Map finalMap =
Utils.getFieldMetaData(Account.getSObjectType().getDescribe(), fieldValueMap.keySet());
// Create the account sObject
Account acct = new Account();
for (String field : fieldValueMap.keySet()) {
// check different data types
if (finalMap.get(field).getType() == Schema.DisplayType.Integer) {
acct.put(field, Integer.valueOf(fieldValueMap.get(field)));
}
if (finalMap.get(field).getType() == Schema.DisplayType.STRING || finalMap.get(field).getType() == Schema.DisplayType.PHONE) {
acct.put(field, fieldValueMap.get(field));
}
// check for other data types ...
}
insert acct;
}
Then later on, you can call the method like this:
Map<String, String> dynamicRecord = new Map<String, String>();
dynamicRecord.put('Name', 'Acme4');
dynamicRecord.put('Phone', '(415)555-1212');
dynamicRecord.put('NumberOfEmployees', '100');
createAccount(dynamicRecord);
Good to know
– Utils.getFieldMetaData at line 4 of createAccount is a utility method for getting field metadata. It’s from Jeff Douglas’s excellent blog and the code can be found in the post “Getting Salesforce Field Metadata the Easy Way“.