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;
}
1
  • @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
    Commented May 21, 2016 at 17:36

1 Answer 1

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.

1
  • 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
    Commented May 21, 2016 at 16:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .