Archive

Archive for April, 2011

Custom Settings : How and Why !?

April 20, 2011 1 comment

Hard-coding and good code are a match made in hell. RecordTypeIds are most vulnerable to this abuse, and we’re are all familiar with the frustration of finding that code that worked in environment A, suddenly stops working when it is promoted to say test. Why? Because possibly RecordTypeIds are different across the two environments.

Why hard-code when you can use Custom Setting for stuff like this ? Custom Settings are a SOQL inexpensive way of storing your configurable parameters in the safe confines of the Salesforce database, with all the conveniences of a custom object – create / edit via point and click – standard salesforce !

Under the hood Custom Settings are much like a Custom Salesforce Object, save for you cant have triggers on them. Most obvious difference, amongst others.

What’s more, they even come in two flavours ! Hierarchical and List.

Hierarchical Custom Settings let you define values at different levels – Org Wide, Profile-wise or even User – Wise. They are accessible in Config (Validation Rules, etc) as well as Apex Code.

List Custom Settings are structured similar to records held in a custom object.

To create your first Custom Setting, navigate to Setup > Develop > Custom Settings

Here you can create your first List or Hierarchical Custom Setting. You will find this menu is similar to the one for creating a custom object. However the types of fields you can create on a Custom Setting are restricted – for eg. no picklists or lookups or formula fields.

Let’s say we created a Custom Setting called Test__c and added Text Fields Value1__c and Value2__c.

Its simple enough to do via the UI – click Manage on the CustomSetting screen, and it will let you add records. Observe the similarity in doing this via Apex

Test__c test = new Test__c(Name='One', Value1__c='1stValue', Value2__c='2ndValue');

insert test;

To access this record we created, we can summon it without SOQL !

Test__c testSelect = Test__c.getInstance('One');

System.assertEquals(testSelect.Value1__c, '1stValue');

Special Considerations for Hierarchical Custom Settings :

We spoke about the ability of Hierarchical Custom Settings to hold different values for a field per Profile, User and Org-wide.

To make this possible, Hierarchical Custom Settings have a field called SetupOwnerId, which holds the Id which the record pertains to.

So, if I wanted to create a record pertaining to user Joe Bloggs

User joeUser = [Select Id from User where Name='JoeBloggs'];

Test__c joesSetting = new Test__c(SetupOwnerId=jobUser.Id, Value1__c='Joe1', Value2__c= 'Joe2');

insert joesSetting;

Then, to access this, you just need to pass in Joe’s Id when you retrieve this Custom Setting instance

Test__c joesTest = Test__c.getInstance(joeUser.Id);

System.assertEquals('Joe1', joesTest.Value1__c);

In summary, to get a reference to a specific List Custom Setting, we use CustomSetting__c.getInstance(NAME), whereas for a specific Hierarchical Custom Setting, it’s CustomSetting__c.getInstance(PROFILE_OR_USERID)

Last, but not the least, CustomSettings are not part of config that would move across in an Environment Refresh or such. The data rows will have to be moved across environments via DataLoader, much like reference data records.

Needless to say, please do read through the Salesforce documentation on Custom Settings : http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_custom_settings.htm

O Reference, why art thou null !? Apex Bloopers Series : 1

April 4, 2011 1 comment

I have recently acquired a penchant for responding to posts on the Salesforce Discussion Boards. Its the only way I know of constantly challenging the limits of my limited knowledge about this rapidly evolving platform.

As part of the Apex Bloopers series, I aim to capture some of the most common mistakes we make inadvertently, and wonder why the Universe is conspiring against us when everything looks like it should ! Some of these are not really mistakes, but some things are just not so obvious when you get started with Apex. So Bloopers, for want of a more catchy title !

The first one that springs to mind is a case where you check for relationship references in a before / after insert trigger.

Now if you try inserting a Contact and look at the debug logs, you will see that con.Account.Name evaluates to null. However the AccountId field does hold the Id of the related Account. That does seem a bit odd when you come across it for the first time. It isn’t exactly intuitive.

The reason this happens is because in before / after insert triggers, relationship fields are not reference-able directly, as there is no way for Salesforce to know which fields of the related object it should load and make available. It cannot load all Account fields and make them available, for reasons of efficiency (err… or so I’m told !)

So, if you need to access fields on related objects, you will first have to query for them and then use the references.

Needless to say (really !?), in a before / after Update trigger, the Contact.Account reference will evaluate to a value !

So much for this time, until we meet again, May the Force.com be with You !

Categories: Uncategorized
%d bloggers like this: