Thursday, February 2, 2012

Detecting the sObject type of Id's from ambiguous fields

When dealing with the OwnerId field, it is important to check if it is a User or a Group sObject you are dealing with before you start using it or you'll get errors. The Task object also has a few ambiguous fields that match up multiple Objects like the WhoId and the WhatId. In triggers and in other logic you will sometimes need to detect what the object is to either exclude or include it in the next bit of code. We dont want to iterate through code and update records if we don't need to, it will bog down the system. 

I have seen some of the ways out there that are used, particularly the one where you check if the first 3 letters of the ID is '500' or '300' but i do not think this is an accurate way of detection. I want one that the system tells me for sure what object it is. Unfortunately its not as dynamic as i would like it to be due to limitations in APEX, but it is still a much better detection than the above. 

I first made a helper class called GlobalHelper_IsSobjectType and populated it with a few methods that look like the following. It takes in the Id and after a check to make sure that an Id was actually passed and is not null, it try's to create an Object of that Type. If it can it will not fall into the Catch and will return true, other wise it will error and return false, but it will not error in a way that will halt your program from finishing(thus why its in a try catch). 

I made one for Account, Contact, Lead, User, and Opportunity since those are the ones I typically have to detect. When it comes to the OwnerId field I can just use the one for User since if it returns false i know its a group. I also found that I needed to Overload the method so it would work with string as well as Id: 

Ideally I was hoping to make the above but make it more dynamic so you pass the object type you wanted to detect as well as the id for the detecting. That way you would only need one method instead of one for each Object, but I have yet to find a way to make it work. Now of course you need to test the code, and I prefer as close to 100% coverage as possible so:

Twitter: @SalesForceGirl  or Facebook

Wednesday, February 1, 2012

APEX Trigger to Prevent Duplicate Object Records

One of the biggest issues in Org's that I have seen is with duplicate records. But what is the best way to prevent this? With an easy trigger of course! 

Let take the Contact object, in my Org, everything is keyed off email, so we shouldn't have more than one contact with the same email address. And we need to not only protect against new Contacts, but we also need to ensure that if a User updates the email on the Contact that it too is not already in use before the update occurs. In order for the User to know that they are trying to Insert or Update incorrectly we will have a field error show next to the email of the contact stating that one already exists.

Lets make(or update) a Contact trigger for before insert and before update. 

We are going to use a Map to store the id and email of each contact that comes into the trigger so we can use that to do a SOQL query later when its time to see if it already exists.  add the 'trigger.isBefore' even though we know this will only occur before, so that this can be easily extended in the future and we wont have to go back and change code.

Now we need to populate the map with the Contact info so we can use it in the SOQL query next. We should also send up an error if the batch of Contacts that is being iterated over in the trigger contains more than one of the same email. 

Now that we have the Map populated, or at least in theory it should be, we will query the DB to see if a Contact already exists with that email, and if so, show an error to the User, other wise do nothing and allow it to be inserted/updated. 

And thats it. You can of course make this much more robust, so it not only compares email but also name and phone number too. 

Twitter: @SalesForceGirl  or Facebook