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
Nadav GrossNadav Gross 

Using triggers to create a relationship when upserting records using external id

Hi everyone,

In our implementation we have two custom objects: Platform_User__c and MRR_Movement__c.  Platform_User__c has an Account_ID__c which serves as an external ID; MRR_Movement__c has an Account_ID__c to allow us to associate the two (but not defined as an external ID, since MRR Movements have a different external ID we use). We've also created Related_Platform_User__c as a master-detail relationship on MRR_Movement__c.

But to my surprise the following trigger, which I built based on the dev documentation on how to relate records using an external id, isn't working:
trigger newMovement on MRR_Movement__c (before insert, before update) {
    for (MRR_Movement__c movement : Trigger.new) {
        Platform_User__c relatedUser = new Platform_User__c(Account_ID__c = movement.Account_ID__c);
        movement.Related_Platform_User__r = relatedUser;
    }
}

This throws a required field missing error for Related_Platform_User__c.

I am pretty sure I'm missing something small and silly, please help a newbie out :)

Raj VakatiRaj Vakati
Try this ..Its it's working let me know i will bulky the code 
 
trigger newMovement on MRR_Movement__c (before insert, before update) {
    for (MRR_Movement__c movement : Trigger.new) {
		
        Platform_User__c pUser = [ Select Id from Platform_User__c where  Account_ID__c = movement.Account_ID__c Limit 1];
    	movement.Related_Platform_User__r = pUser.Id;
    }
}

 
Raj VakatiRaj Vakati
bulkfied version 
trigger newMovement on MRR_Movement__c (before insert, before update) {
	
	Set<Id> accIds = new Set<Id>() ; 
    for (MRR_Movement__c movement : Trigger.new) {
		addIds.add(movement.Account_ID__c) ; 
    }
	List<Platform_User__c> pUser = [ Select Id from Platform_User__c where  Account_ID__c IN : accIds];
    Map<Id,Id> acctoptuser = new Map<Id,Id>() ; 
	for(Platform_User__c pltU : pUser){
		acctoptuser.put(pltU.Account_ID__c , pltU.id);
	}
	
	  for (MRR_Movement__c movement : Trigger.new) {
		         movement.Related_Platform_User__r = acctoptuser.get(movement.Account_ID__c);

    }
	
}

 
Nadav GrossNadav Gross
Hey Raj,

Thanks for your message! I've actually tried that before posting, and it works; It's just that after reading the Salesforce article below I thought we may be able to do this without SOQL, since MRR movements will be added on a daily basis at bulk.

Here's the article that seems to suggest SOQL isn't needed:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_nested_object.htm
Nadav GrossNadav Gross
In case anyone else is looking at this, just to correct a few small errors in Raj's code:
trigger newMovement on MRR_Movement__c (before insert, before update) {
    Set<String> accountIds = new Set<String>(); 
    for (MRR_Movement__c movement : Trigger.new) {
        accountIds.add(movement.Account_ID__c); 
    }
    List<Platform_User__c> platformUsers = [SELECT Id,Account_ID__c FROM Platform_User__c WHERE Account_ID__c IN :accountIds];
    Map<String,Id> accountToSF = new Map<String,Id>(); 
    for(Platform_User__c platformUser : platformUsers){
        accountToSF.put(platformUser.Account_ID__c , platformUser.id);
    }
    for (MRR_Movement__c movement : Trigger.new) {
        movement.Platform_User__c = accountToSF.get(movement.Account_ID__c);
    }
}


This works, but I am still looking for a way to do this without SOQL if anyone has any.