[SalesForce] Update Multiple values for record in Apex Trigger

I have custom junction object between user and custom object. I need to update user record with junction object values for given user. Each user may have more than one record in junction object.

Example: User1 will have account1,account 2 in junction object and I need to update user record custom field with account1, account2.
I have written code like this but it will overwrite the previous value with new value in given batch when I issue single update list statement. How can I achieve it?

trigger UpdateUserGUL on GUL_Account_to_User_Junction__c (after insert) {
    String AccountName;
    String ChatterGrpName;
    List<User> userList = new List<User>();

    for (GUL_Account_to_User_Junction__c j: Trigger.New) {
        User userRecord = new User();
        userRecord.Id = j.UserId__c;
        //check to see if it is having any value
        AccountName = userRecord.GUL_Account_Default__c;
        if(AccountName == null) {
            userRecord.GUL_Account_Default__c = j.GUL_Account_Name__c;
        } else { 
            userRecord.GUL_Account_Default__c = AccountName + ',' + j.GUL_Account_Name__c;
        }   

        userList.add(userRecord);
    }
    update userList;
}

Best Answer

If I were you, I would implement this with dlrs.

  • Parent Object: User
  • Relationship Field: UserId__c
  • Child Object: GUL_Account_to_User_Junction__c
  • Field To Aggregate: GUL_Account_Name__c
  • Aggregate Operation: Concatenate Distinct
  • Aggregate Result Field: GUL_Account_Default__c
  • Concatenate Delimiter: ,

If you want to roll your own solution, you are going to have to query the sibling records, and don't forget you need to worry about the delete case.

Map<Id, Set<String>> userIdToAccountNames = new Map<Id, Set<String>>();
for (Junction__c junction : trigger.new)
{
    if (!userIdToAccountNames.containsKey(junction.UserId__c))
        userIdToAccountNames.put(junction.UserId__c, new Set<String>());
    userIdToAccountNames.get(junction.UserId__c).add(junction.GUL_Account_Name__c);
}
for (Junction__c existing : [
    SELECT UserId__c, GUL_Account_Name__c FROM Junction__c
    WHERE UserId__c IN :userIdtoAccountNames.keySet()
]) userIdToAccountNamees.get(existing.UserId__c).add(existing.GUL_Account_Name__c);

List<User> users = new List<User>();
for (Id userId : userIdToAccountNames.keySet())
{
    String concat = String.join(new List<String>(userIdToAccountNames.get(userId)), ',');
    users.add(new User(Id=userId, GUL_Account_Default__c=concat));
}
update users;

You should really consider adding error handling to the update operation. You may also need to put this functionality in a without sharing class, since most users won't be able to update other User records.