function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
jack-cepheidjack-cepheid 

Trigger to update Related user

I'm new to Apex in general and cannot seem to get this trigger to work...

I have a custom object LOC that has a related custom object called GPO.

I need to have a trigger that will update a related user field on LOC with the owner of the related GPO.

 

I need the related user so I can use it in an approval process.

 

Here is what I have so far and it does nothing. From my research I know maps are needed but I don't understand the concept at this point.

 

trigger LOCapprover on LOC__c (before insert,before update) {
    for(LOC__c loc: Trigger.new){
        if(loc.LOC_GPO__c != null)
    loc.Receiving_User__c = loc.LOC_GPO__r.Owner.Id;  
        
    }    
}

 

Best Answer chosen by Admin (Salesforce Developers) 
JohnSchultzJohnSchultz

The problem is this line:

if (loc.Account__r.GPO_Affiliation__c != null)....

 

You are trying to access related records again there, which will always result in null, which means that nothing gets added into the ID set.

 

Instead you'll need to move the related object request out to the query. Try something like this:

trigger AccountGPOapprover on LOC__c (before insert, before update) {
    Set<Id> accountIDs = new Set<Id>();
    
    for (LOC__c loc : Trigger.new) {
        if (loc.Account__c != null) {
            accountIDs.add(loc.Account__c);
        }
    }
    
    Map<Id, Account> accounts = new Map<Id, Account>([select Id, GPO_Affiliation__r.Owner.Id from Account where Id in : accountIDs]);
    
    for (LOC__c loc : Trigger.new) {
        if (loc.Account__c != null && accounts.containsKey(loc.Account__c)) {
            loc.Losing_User__c = accounts.get(loc.Account__c).GPO_Affiliation__r.Owner.Id;
        }
    }
}

 

All Answers

JohnSchultzJohnSchultz

Triggers won't give you immediate access to related records like you're trying to do there. Instead, you'll need to do a query yourself to get that information.

 

You could do it like this (though I would typically prefer to perform the query and logic in a class than directly in the trigger)...

 

trigger LOCapprover on LOC__c (before insert,before update) {
    Set<Id> gpoIDs = new Set<Id>();
    
    for (LOC__c loc : Trigger.new) {
        if (loc.LOC_GPO__c != null) {
            gpoIDs.add(loc.LOC_GPO__c);
        }
    }
    
    Map<Id, GPO__c> gpos = new Map<Id, GPO__c>([select Id, Owner.Id from GPO__c where Id in : gpoIDs]);
    
    for (LOC__c loc : Trigger.new) {
        if (loc.LOC_GPO__c != null && gpos.containsKey(loc.LOC_GPO__c)) {
            loc.Receiving_User__c = gpos.get(loc.LOC_GPO__c).Owner.Id;
        }
    }
}

 

jack-cepheidjack-cepheid

Thanks that works great. My other question is this... Is it possible to reference a related objects related object? (example an LOC that is related to an Account and that Account is related to a GPO)

If that is possible will the existing map that the trigger has created allow me to pull the owner ID from the Accounts related GPO or is that asking too much of a trigger?

 

JohnSchultzJohnSchultz

You can do that kind of relational lookup in the SOQL query, like:

select Id, .... Account.GOP__c from LOC__c where .....

jack-cepheidjack-cepheid

Okay

I tried to write (well modified the one you posted) a separate trigger that would find the owner id of the related Accounts related GPO and there are no errors yet it does nothing.

Do i need to point the query to the account. record on this trigger?

trigger AccountGPOapprover on LOC__c (before insert, before update) {
	Set<Id> gpoIDs = new Set<Id>();
    
    for (LOC__c loc : Trigger.new) {
        if (loc.Account__r.GPO_Affiliation__c != null) {
            gpoIDs.add(loc.Account__r.GPO_Affiliation__c);
        }
    }
    
    Map<Id, GPO__c> gpos = new Map<Id, GPO__c>([select Id, Owner.Id from GPO__c where Id in : gpoIDs]);
    
    for (LOC__c loc : Trigger.new) {
        if (loc.Account__r.GPO_Affiliation__c != null && gpos.containsKey(loc.Account__r.GPO_Affiliation__c)) {
            loc.Losing_User__c = gpos.get(loc.Account__r.GPO_Affiliation__c).Owner.Id;
            
        }

    }
}

 

 

JohnSchultzJohnSchultz

The problem is this line:

if (loc.Account__r.GPO_Affiliation__c != null)....

 

You are trying to access related records again there, which will always result in null, which means that nothing gets added into the ID set.

 

Instead you'll need to move the related object request out to the query. Try something like this:

trigger AccountGPOapprover on LOC__c (before insert, before update) {
    Set<Id> accountIDs = new Set<Id>();
    
    for (LOC__c loc : Trigger.new) {
        if (loc.Account__c != null) {
            accountIDs.add(loc.Account__c);
        }
    }
    
    Map<Id, Account> accounts = new Map<Id, Account>([select Id, GPO_Affiliation__r.Owner.Id from Account where Id in : accountIDs]);
    
    for (LOC__c loc : Trigger.new) {
        if (loc.Account__c != null && accounts.containsKey(loc.Account__c)) {
            loc.Losing_User__c = accounts.get(loc.Account__c).GPO_Affiliation__r.Owner.Id;
        }
    }
}

 

This was selected as the best answer
jack-cepheidjack-cepheid

Absolutely amazing. I think I'm starting to understand the syntax of the Map method.

 

Thank you so much. My companies normal Apex guy is on an extended vacation so I was left to hack my way through the weeds alone.

I have a few small tweaks to make but this is fantastic.