[SalesForce] Need help in the attempt to follow a ‘best practice’ for writing triggers

I have read that it is a considered a best practice when writing a trigger to have as little code as possible in the trigger itself, and to instead call a class from the trigger. I wrote a trigger that did this, and as an 'After' trigger, it worked, however, I ran into an issue when I realized that it should actually be a 'Before' trigger.

I followed a template that suggested passing trigger.new to the class as a list, however, this (I think) prevented me from looping over trigger.new in the class when making my field updates, so the field changes weren't being committed to the database. Is there a way to loop over a list containing the same sObjects as trigger.new and have the changes commit to the database?

I have since abandoned the best practice and brought all of the code directly into the trigger's body, looping over trigger.new, and it works as it should, but, as a new developer, I would like to stick to best practices when possible, so any incite would be appreciated!

Thanks!

NEW CODE: Thanks for the help so far!

Trigger:

trigger transferRelationshipTeamFromAcct on Financial_Account__c (before insert, before update) {
    FinancialAccountManager.handleUpdateTransferRelationshipTeamFromAcct(trigger.new);
}

Class:

public class FinancialAccountManager {
public static void handleUpdateTransferRelationshipTeamFromAcct(List<Financial_Account__c> FinAcctsNewMap){
    Map<Id, Financial_Account__c> mapFinAccts = new Map<Id, Financial_Account__c>();

    for(Financial_Account__c finAcct : [
        SELECT Id, 
            Wealth_Advisor_Lookup__c, Portfolio_Manager_Lookup__c, Trust_Officer_Lookup__c,
            Other_Team_Member_1_Lookup__c, Other_Team_Member_2_Lookup__c,
            client__c, client__r.Wealth_Advisor__c, client__r.Portfolio_Manager_Lookup__c,
            client__r.Trust_Officer__c, client__r.Other_Team_Member_1__c, client__r.Other_Team_Member_2__c
        FROM Financial_Account__c
        WHERE Id IN :trigger.new
    ]){
        mapFinAccts.put(finAcct.Id, finAcct);
    }

    for(Financial_Account__c finAcct : FinAcctsNewMap){
        finAcct.Wealth_Advisor_Lookup__c = mapFinAccts.get(finAcct.Id).client__r.Wealth_Advisor__c;
        finAcct.Portfolio_Manager_Lookup__c = mapFinAccts.get(finAcct.Id).client__r.Portfolio_Manager_Lookup__c;
        finAcct.Trust_Officer_Lookup__c = mapFinAccts.get(finAcct.Id).client__r.Trust_Officer__c;
        finAcct.Other_Team_Member_1_Lookup__c = mapFinAccts.get(finAcct.Id).client__r.Other_Team_Member_1__c;
        finAcct.Other_Team_Member_2_Lookup__c = mapFinAccts.get(finAcct.Id).client__r.Other_Team_Member_2__c;
    }
}
}

Best Answer

Here you go - this should work for both Inserts and Updates

public class FinancialAccountManager {
public static void handleTransferRelationshipTeamFromAcct(List<Financial_Account__c> FinAcctsNewMap){

Set<Id> clients = new Set<Id>{};

for(Financial_Account__c finAcct : finAcctsNewMap){
clients.add(finAcct.Client__c); //collect all the client Ids we are interested in

}

//Query the client attributes
    Map <Id, Client__c> clientsMap = new Map<Id, Client__c)([
        SELECT Id, Wealth_Advisor__c, Portfolio_Manager_Lookup__c,Trust_Officer__c, Other_Team_Member_1__c, Other_Team_Member_2__c
        FROM Client__c
        WHERE Id IN :clients]);


    for(Financial_Account__c finAcct : FinAcctsNewMap){

           finAcct.Portfolio_Manager_Lookup__c = clientsMap.get(finAcct.Client__c).Portfolio_Manager_Lookup__c;

            finAcct.Trust_Officer_Lookup__c = clientsMap.get(finAcct.Client__c).Trust_Officer_Lookup__c ;

            finAcct.Other_Team_Member_1_Lookup__c = clientsMap.get(finAcct.Client__c).Other_Team_Member_1_Lookup__c ;

            finAcct.Other_Team_Member_2_Lookup__c = clientsMap.get(finAcct.Client__c).Other_Team_Member_2_Lookup__c ;
    }

  }
Related Topic