Wednesday, 31 August 2011

Dreamforce Day 1

Dreamforce day 1 was a blast. Partner keynote threw up a few nuggets around certification and investment. I had to dip out of this a little early to attend the Force.com MVP networking lunch. A table chock full of superstars! Afternoon was session time, including an excellent deep dive into single sign on. I'm writing this while waiting for the keynote to start - MVP seating is in the VIP section, and I'm about 5 rows back from the action and Marc Benioff has just walked past looking pretty relaxed given there's 14000 excited people here to listen to him. - Posted using BlogPress from my iPad

Location:Brannan St,San Francisco,United States

Tuesday, 30 August 2011

Dreamforce, baby!

So excited to be in San Francisco for Dreamforce 2011.  This is my second Dreamforce, but my first as an attendee.  Last year BrightGen were part of the Cloud Expo, so I was chained to a stand and trapped in a suit and tie. This year I'm looking forward to some deep dive sessions and networking with my fellow MVPs.

Due to late flight booking etc we didn't arrive until 7pm on Monday night after 20+ hours travelling and a hop through LAX.  After a quick turn and burn at the hotel, we headed off to Union Square for dinner and within 30 minutes had bumped into about 25 people that we knew!  Dreamforce takes over this town.

I'll be attempting some blog entries and twitter updates (along with 40,000+ others no doubt) as the week progresses, so stay tuned.

Friday, 26 August 2011

Force.com MVP



This week I was both delighted and honoured in equal measure to be chosen to join the Force.com MVP program as part of the Summer 11 intake.  Looking at the other members I'm in some pretty stellar company - breathing the same rare air as the likes of Wes Nolte and Jeff Douglas still seems a little unreal.

The MVP term is one year, after which your contribution is re-assessed to make sure you still deserve your membership.  I like this feature as it ensures that everyone stays at the top of their game.

I'd like to take this opportunity to thank all those that nominated me for the MVP program, but special thanks go to Abhi who has been unstinting with his encouragement.

Saturday, 13 August 2011

DML During Initialisation

I ran into a situation recently where I wanted to be able to insert a record as part of the construction of a Visualforce controller, which the user then edited. As we all know, DML is not allowed in the constructor, so I started investigating alternatives.

One mechanism is to create an interim Visualforce page with a page action attribute tied to a controller method that inserts the record and then redirects the user to the actual Visualforce edit page. The downside to this method is that I would end up with two pages and two controllers, as its not safe for this to be incorporated into a single controller due to the fact that order of execution cannot be guaranteed.

An alternative solution, and the route that I chose to go, is to use javascript to invoke an action method on the controller, and have this action method carry out the DML operation. In order to ensure that this doesn't happen every time that the page is refreshed, I have an "initialised" flag in my controller that is set to false in the constructor, and updated to true once the DML has taken place.

The controller is shown below:
public class InsertObjectController 
{
 public Boolean initialised{get; set;}
 public Account acc {get; set;}
 
 public InsertObjectController()
 {
  initialised=false;
 }
 
 public void init()
 {
  if (!initialised)
  {
   acc=new Account();
   acc.Name='Blog Account';
   insert acc;
   initialised=true;
  }
 }
}

On the page side, the main change was to put out a please wait spinner while the initialisation was going on, so that the user wasn't tempted to start entering data while the initialisation was taking place. The DML operation is executed via an actionfunction tied to the onload handler, and once this completes the main body of the page is rerendered, replacing the spinner with the newly inserted record detail (including the id of the account).

Note that it this will overwrite any existing onload handler - for details of how to add a function to the end of the existing onload handler see this blog post.

The page markup is shown below:

<apex:page controller="InsertObjectController">
  <apex:form >
    <apex:actionFunction name="doInit" action="{!init}" rerender="allPanel"/>
    <apex:outputPanel id="allPanel">
      <apex:outputPanel rendered="{!NOT(initialised)}">
        <p align="center" style='{font-family:"Arial", Helvetica, sans-serif; font-size:20px;}'><apex:image value="/img/loading.gif"/>&nbsp;Please wait</p>
        <script>
           window.onload=function()
           {
             doInit();
           };
        </script>
      </apex:outputPanel>
      <apex:outputPanel rendered="{!initialised}">
        <apex:pageBlock title="Account Details">
          <apex:pageBlockSection >
            <apex:inputField value="{!acc.id}"/>
            <apex:inputField value="{!acc.name}"/>
            <apex:inputField value="{!acc.type}"/>
            <apex:inputField value="{!acc.industry}"/>
          </apex:pageBlockSection>
        </apex:pageBlock>
      </apex:outputPanel>
    </apex:outputPanel>
  </apex:form>
</apex:page>

Saturday, 6 August 2011

Second London Force.com Developer Meetup / Deploying

This week saw the second London Force.com Developer Meetup at the Skills Matter eXchange, with a three handed talk on Team Development Strategies on the Force.com Platform from Wes Nolte, Anup Jadhav and Laurent Delcambre.  This time the meetup was captured on video - you can view it at: http://skillsmatter.com/podcast/nosql/team-development-strategies. There were also prizes on offer for answering snap questions from the presenters - I managed to come away with a Ruby on Rails book and a Salesforce.com T-Shirt.


One of the more interesting topics of discussion for me was around deploying changes between sandbox and production.  Like many Force.com developers I suspect, all my early deployments were carried out using the Force.com IDE, highlighting the elements I wanted to deploy, right-clicking and going through the deploy to server wizard.  This gives a nice visual indicator of the changes that will be made on the target system:



However, there are a couple of downsides to this:
  • If the deployment fails, you have to start over from scratch.  Not too bad if there's only a couple of files like my example deployment above, but a bit tedious once you get into double figures.
  • The changes aren't repeatable.  If I want to deploy those same files to another org at a later date, that's only possible if no additional changes have been made.
For these reasons I tend to use change sets these days, although these only work between connected organizations (e.g. sandbox to production or between sandboxes associated with the same production org).

Change sets are persistent, so when working on a piece of development you can add the new/changed elements as they are created.  Once you are ready to deploy, you upload the change set to the target org which locks the elements in their current form.  This means that if you need to deploy to a separate org (a training sandbox for example), it doesn't matter when you do this, the change set will be in exactly the same state as when it was first uploaded.  I've found this aspect to be particularly useful when I have a large amount of changes to deploy to production - I can test out deploying to a pre-production sandbox and once I've ironed out the issues, I can simply "replay" the change set into production.

If the deployment of a change set fails, you can simply clone the change set, fix the problem and then upload it again.  An important point to note is that when you clone the change set, you get the latest version of each of the elements in the new change set.

Change sets aren't a silver bullet though - being limited to connected org means that you must be developing in a sandbox to use them.  If you are working in a Developer Edition, they won't be available.  They also tend to be slower than using the IDE - something that can become important when you have to wait 30 minutes for the latest attempt at the change set to be uploaded at 1am in the morning.  Less of a regular issue, but still an issue nonetheless, is that they tend to be fragile around Salesforce.com releases - sometimes the upload takes a couple of days to become available, while at other times it doesn't make its way to the target org at all.  I'd imagine this is down to the source and target orgs being at different versions (e.g. sandbox at Summer 11 but production at Spring 11).  Where possible, we always look to avoid major deployments to production in the run up to these upgrade windows.

The next meetup is planned for October/November time - I'm looking forward to it already.