I need some help with a trigger. I want the role to dictate what public group a user is made a member of. I am trying to write this as a bulkified trigger using good SOQL form where there aren't any inside of loops. I can't figure however how to find a value in a list.

Can someone help me out?

trigger UserPublicGroupMembership on User (after insert, after update ) {

    List<GroupMember> gpMember = new list<GroupMember>();
    List<Group> pubGroup = new list<Group>([
        Select ID,Name 
        FROM Group

    //Put user in group if insert
        for(User u:trigger.new){
            IF (u.UserRole.Name == 'BCS'){
                //Get Group Id from pubGroup list using Name. 
                Id GroupId = ???
                //Put both the group ID and User ID into the gpMember list
                gpMember.add(GroupId, u.Id); //??? Does this work ???

            IF (u.UserRole.Name == 'BCS Manager'){
            //same process as for BCS

            //so on and so on for all our roles. 

    //Check if profile or role changed, then put user in group if true


    //Nnow that list is populated insert. 
    //Always doing an insert as system doesn't care about existing membership conflicts. 
    Insert gpMember;


1 Answer 1


You have a couple issues. First, you should adopt a trigger handler methodology. There are many out there, do some research and find one that works for you.

Next, see: Parent and children relationships accessible via trigger? You need to update your reference to UserRole, because your current approach won't work. You can map them by name with something like:

Map<String, UserRole> roles = new Map<String, UserRole>();
for (UserRole role : [
    SELECT Name FROM UserRole WHERE Id IN (
        SELECT UserRoleId FROM User WHERE Id IN :trigger.new
]) roles.put(role.Name, role);

You can do something similar for your Group records, though I'm not sure how you will filter them. Perhaps the naming convention is that they will have the same name as the UserRole? If so, you could do:

Map<String, Group> groups = new Map<String, Group>();
for (Group group : [SELECT Name FROM Group WHERE Name IN :roles.keySet()])
    groups.put(group.Name, group);

Once you have these collections, referencing them will avoid queries inside a loop.

for (User user : trigger.new)
    UserRole role = roles.get(user.UserRoleId);
    if (role != null)
        Group group = groups.get(role.Name);
        // do stuff with this information

You must log in to answer this question.

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