Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have a rather simple Trigger. When fired it determines its own type and calls an appropriate function in Trigger handler class.

trigger Project_Trigger on Acme_Project__c (before insert, after insert, before update) {
    if (Trigger.isBefore) {
        if (Trigger.isInsert) {  
            ProjectHandler.projectBeforeInsert(Trigger.new);
        }
        ...
    }
    ...
}

Trigger handler class takes Trigger.old/Trigger.new and performs all required logic.

public class ProjectHandler {
    public static void projectBeforeInsert(List<Acme_Project__c> newProjects) {
        ...
    }
}

I would like to make the handler class work for many different Custom Objects, not only for Acme_Projects__c. In fact I already have those Custom Objects and I can just clone the class and find/replace 'Acme' with, for instance, 'Some_Other_Client', but that seems too repetitive.

My idea is to create an intermediary Custom Object, like Clipboard_Project__c, and use it to populate with Trigger.old/Trigger.new values, perform class handler methods on instances of that Custom Object, and then return everything back to trigger to do final DML operations...

In the Trigger -

Clipboard_Project__c[] newProjects;

for (Acme_Project__c p : Trigger.new) {
    Clipboard_Project__c one = new Clipboard_Project__c(
        Id = p.Id,
        Field_1__c = p.Field_1__c,
        ...);
    newProjects.add(one);
}

ProjectHandler.projectBeforeInsert(newProjects);

//some code that puts newProjects back into Trigger.new

delete(newProjects);

Is this a viable approach? How do I put newProject contents back into Trigger.new (as far as I understand that's the only way to make Custom Object instances update)?

share|improve this question

1 Answer 1

up vote 4 down vote accepted

Apex has support for generic sObjects. You can do pretty much anything with a generic sobject that you could do with a specific sObject type (get/set fields, dml operations, etc.) So you could write your generic handler as follows:

public class myTriggerHandler {
    public static void BeforeInsertHandler(List<Sobject> newRecords) {
        ...
    }
}

There is no reason to pass anything back to the triggers as you can perform everything in the trigger handler. The best practice is to have a simple trigger that delegates all the actual work to a trigger handler. If you have slightly different logic for the different types of sObjects:

public class myTriggerHelper {
    public static void doGenericLogic(List<Sobject> newRecords) {
        ...
    }
}

public class ProjectHandler {
    public static void projectBeforeInsert(List<Acme_Project__c> newProjects) {
        myTriggerHelper.doGenericLogic(newProjects);
        ...
    }
}
share|improve this answer
    
Thanks grigriforce, SObject type seems to work. However, I get an error when trying to perform logic in the handler - for (SObject p : newProjects) { if (p.Stage__c != 'Complete') { String type = p.Project_Type__c; ... } }. The erro is 'Field expression not allowed for generic SObject'. –  dfo Jan 21 '13 at 13:35
    
you have to access them dynamically since it doesn't know what fields exist on the Sobject (or cast to the appropriate sObject type). p.get('Stage__c')..type = (String) p.get('Project_Type__c) –  Greg Grinberg Jan 21 '13 at 14:45
    
That's very helpful. Thanks! –  dfo Jan 21 '13 at 22:13
    
As @grigriforce mentioned, you've got to take the generic sObject type and determine it's concrete type in order to access the fields. Inside the helper method you can use the sObject describe info to determine the object type and act accordingly. if (yourObject.getsObjectType() == Acme_Project__c.sObjectType) { /* cast each item to the Acme_Project__c class and perform logic */ Acme_Project__c aproject = (Acme_Project__c)listItem; aproject.Project_Type__c = ...; } –  Mark Pond Jan 22 '13 at 16:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.