1

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;
}
  • @adrianlarson I think existing records query needs to be against User object to get existing Account field value for that user to add to the list.Am I correct? – crmsj May 21 '16 at 17:36
1

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.

  • I think existing records need to be queried against records entering into batch.I see in your code you queried against junction object.Problem is given batch may have more than one record for user before updating users List. help needed. – crmsj May 21 '16 at 16:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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