Overload Apex Class to be Controller AND Extension
Wow - today brought an interesting discovery. Here's the situation:
Coding the new premium version of Mass Update Contacts (details to come), I replaced the two parts of the page with Apex Components. This will allow the app to support custom address fields and international address formats.
I didn't want to write one ControllerExtension for the main page, a CustomController for the view section component, and another CustomController for the pageblocktable component. So here is the overloaded class constructor. Note that this works because an extension passes the StandardController to the constructor, and a CustomController passes nothing:
public with sharing class VersatileClass {
private Account account;
public VersatileClass(){
system.debug('OPERATING AS CONTROLLER');
if(System.currentPageReference().getParameters().get('id')==null){
//Include error checking here
} else{
string AId = System.currentPageReference().getParameters().get('id');
account = [select id, name from Account where id = :AId];
//And whatever else you want to do
}
}
public VersatileClass(ApexPages.StandardController controller) {
system.debug('OPERATING AS EXTENSION');
if(System.currentPageReference().getParameters().get('id')==null){
//Include error checking here
} else{
this.account = (Account)controller.getRecord();
//And whatever else you want to do
}
}
}
Enjoy! This should save people a lot of time.
Eclipse as a Password Manager
Caution: Only use this tip if your computer is SECURE.
Recently, Judi Sohn wrote about a URL hack to save your Salesforce username and password (in an exposed, plaintext manner). This is a great way to save a lot of time logging into Salesforce.
There is another way to save un/pw combinations: Use Eclipse to store the un/pw/securitytoken. There's a catch (there always is): Once they're entered, you can't see them in plaintext for, say, doing a copy/paste of your token into Connect for Outlook, Excel Connector, etc.
For each client, I create a project in the Eclipse Force.com IDE, entering the username, password, and security token into the appropriate form. (This does require me to have a System Administrator, or at least "View All Data" and possibly "Edit All Data" profile permissions.) Then, instead of getting into Salesforce through the browser, I open a file in the project, such as an Apex Class, right-click, and select "Show in Salesforce Web." The browser does the rest, opening the org, and taking me to that Apex Class. It does not take me to the Home screen, but I'm willing to use that one extra click. Plus, it's nice to get directly into the Setup area sometimes.
That's it! Keep all your projects in Eclipse, and (as long as you're a developer and work in Eclipse a lot) it will save time.
To reiterate the above caution: Anyone who can open Eclipse can get into any of those orgs, so be careful with this! Always secure your computer. On Vista, require a password when waking from the screen saver, and use other security features whenever possible.
Pulling Code Out of Triggers
To date, triggers have only been accessible on each object's setup page, leading to a lot of hunting for code within the Salesforce CRM application. Even in Eclipse, switching between the Class and Trigger folders for a given project can be a pain.
These pains can partially be alleviated by keeping all Apex code in one place--as Apex Classes. With the addition of a consolidated trigger list in Summer09, some may feel that this post is superfluous, but consolidating code in one place, combined with the trigger list, will lead to a better development, debugging, and org administration experience.
First, here's a sample trigger (written by Jeff Douglas):
trigger AddOwnerColor on Account (before insert, before update) {
// create a set of all the unique ownerIds
Set<Id> ownerIds = new Set<Id>();
for (Account a : Trigger.new)
ownerIds.add(a.OwnerId);
// query for all the User records for the unique userIds in the records
// create a map for a lookup / hash table for the user info
Map<Id, User> owners = new Map<Id, User>([Select Favorite_Color__c from User Where Id in: ownerIds]);
// iterate over the list of records being processed in the trigger and
// set the color before being inserted or updated
for (Account a : Trigger.new)
a.Owner_Favorite_Color__c = owners.get(a.OwnerId).Favorite_Color__c;
}
Let's pull the code from the trigger into an Apex Class and leave a reference to that class & method in the trigger. We need to pass the list Trigger.new as a parameter to the new class's method:
The trigger:
trigger AddOwnerColor on Account (before insert, before update) {
AccountTriggers.AddOwnerColor(Trigger.new);
}
And the class:
public class AccountTriggers {
public static void AddOwnerColor(Account[] accts) {
// create a set of all the unique ownerIds
Set<Id> ownerIds = new Set<Id>();
for (Account a : accts)
ownerIds.add(a.OwnerId);
// query for all the User records for the unique userIds in the records
// create a map for a lookup / hash table for the user info
Map<Id, User> owners = new Map<Id, User>([Select Favorite_Color__c from User Where Id in: ownerIds]);
// iterate over the list of records being processed in the trigger and
// set the color before being inserted or updated
for (Account a : accts)
a.Owner_Favorite_Color__c = owners.get(a.OwnerId).Favorite_Color__c;
} // close AddOwnerColor
}
While this may seem trivial, it has a few advantages:
- Easier to work in Eclipse (all code in the Classes section)
- Easier to write test code (can see tests and their associated methods in one place)
- Can promote code reuse by allowing other classes and triggers to call the same method.
- For those who like to include test code in the same class as the regular Class, this allows them to do so.
There's a catch (there always is):
You should comment into your Class which trigger is calling the class because otherwise, it is almost impossible to see at a glance where the code flows. This will especially help when writing and debugging tests.
Just a matter of personal style: It may be a good idea to write an Apex Class for each object's triggers (such as class AccountTriggers above). Code reuse is still possible, but it can track where triggers were originally used.
Happy coding!
Developer Preview Releases for the Google Visualization API
Dreamforce 2008 brought many exciting new features from salesforce.com, both on the CRM/front-end side and the Force.com platform/back-end side. One of the favorites was the announcement that salesforce.com had released a Google Visualization code share project. Google has invited developers to participate in Developer Preview Releases for the Visualization API.
It looks like a pretty cool way to work on RESTful integrations while making some pretty pictures for your users.
For those unfamiliar with the Salesforce/Google Visualization toolkit, developer.force.com has a great introduction.
How to Deploy QUICKLY Between Orgs
I just came across one of the most useful posts on developer.force.com that I have ever seen:
Jesse Lorenz provides full instructions (along with a best-practice) on deploying quickly from one org to another using the Eclipse IDE.
Read it at http://wiki.apexdevnet.com/index.php/Deploy_Force.com_Applications_Faster. You’ll be glad you did.
[Update: Jesper Joergensen just wrote a super follow-up on deployments in the upcoming Winter 09 release at http://blog.sforce.com/sforce/2008/09/set-up-orgs-4-t.html





