I've seen a lot of coders put the following into their custom Visualforce controllers:
public PageReference customsave() { try{ insert acct; } catch (DMLException e) { /*do stuff here*/ } PageReference acctPage = new PageReference ('/' + acct.id}; acctPage.setRedirect(true); return acctPage; }
I've decided that I don't like this approach. It feels too much like a URL hack, and though I'm sure that it will always work (meaning that salesforce.com will never change its way of referring to a record by /<recordID>
), I'd like to suggest a different method that may use more resources, but will leverage standard controllers, possibly future-proofing the application:
public PageReference customsave() { insert acct; //Error handling removed for brevity. ALWAYS try/catch! ApexPages.StandardController sc = new ApexPages.StandardController(acct); PageReference acctPage = sc.view(); acctPage.setRedirect(true); return acctPage; }
What do you think? Does anyone have coding-style tips to share?
Jeremy Ross says
I agree it’s good to do this where you can. Unfortunately, there are many cases where the URL you need isn’t available from a controller method. In these cases, it’s probably best to have an interface responsible for handing out URLs so that at least you’ve contained URL hacking to one class.
Salesforce’s own PS team hard codes to URLs all the time, esp for things like passing form values in the URL. If they ever decide to change their URL structure, they’re going to have a lot of unhappy customers and/or a lot of work to do.
Sebastian Wagner says
Some time ago I stumbled over Ian Zepp’s Agile Process Management (OSS) CodeShare Project (http://developer.force.com/projectpage?id=a06300000060Zd3AAE), where he made extensive use of a virtual controller class, containing common methods for visualforce, allowing him to keep his code DRY. I was so excited about that class, I decided to follow his lead, and modified it to meet our requirements.
Today our code base is literally based on 5 abstract / virtual classes, we couldn’t live without anymore
* CommonAbstractController
one of the methods is saveAndView() upserts the standard controller record and redirects to the Controller view
# Code: http://snipt.org/xtmh
# removed all of our org specified code and included the unitTests, feel free to use
if you are interested in source code of the classes below, let me know, I’am happy to share it.
* CommonAbstractObject
our core class almost every value class (SalesOrder, ServiceContractLine, …) extends, makes ’em selectable, maintains a rowPosition, generates unique Ids even for unsaved objects, allows to define dynamic child relationships ….
* CommonAbstractContainer
custom collection class for bulk handling CommonAbstractObjects, coulded live without it
* LineItemAbstract
in addition to the CommonAbstractObject LineItem clases extend it, for value rollups and other line item specific methods.