3

I'm a total newbie who is essentially trying to write his first trigger.

Right now, I have a multi-value field in an object. I would like to create a new record for each value in that field.

This is the closest code I could find to try and show my intention :

trigger AutoCreateInterviewer on Position__c (after insert) {
    List<Interviewer__c> interviewers = new List<Interviewer__c>();

    //For each position processed by the trigger, add a new  

    //interviewer record for the specified hiring manager.  

    //Note that Trigger.New is a list of all the new positions  

    //that are being created.  

    for (Position__c newPosition: Trigger.New) {
        if (newPosition.Hiring_Manager__c != null) {
            interviewers.add(new Interviewer__c(
                        Name = '1',
                        Position__c = newPosition.Id,
                        Employee__c = newPosition.Hiring_Manager__c,
                        Role__c = 'Managerial'));
        }
    }
    insert interviewers;
}

Basically, imagine the Hiring_Manager_c field had multiple values in it ( [John, Stacy, Robert] ) . I would like to create a new Interviewer_c record for each one of those people.

Somehow I have to figure out a way to get it to iterate through the values in the Hiring_Manager__c field. I guess I need to use something like this :

Iterate through a list

...but I'm having trouble figuring out how to apply that to the trigger.

Thank you very much for any help you can supply. I'm very grateful for your time and effort.

UPDATE - USING THE UPSERT INSTEAD OF THE INSERT :

In order to use this as an Upsert instead of an Insert I will need to do something like this :

Account[] acctsList = [SELECT Id, Name, BillingCity
    FROM Account WHERE BillingCity = 'Bombay'];
for (Account a : acctsList) {
    a.BillingCity = 'Mumbai';
}

Account newAcct = new Account(Name = 'Acme', BillingCity = 'San Francisco');
acctsList.add(newAcct);
try {
    upsert acctsList ;
}  catch (DmlException e)  {
    System.debug(e.getMessage());
}

So, in the example which Jesse showed below, would I be able to just replace this line :

insert interviewers;

with this ? :

try {
        upsert interviewers Hiring_Manager__c ;
    }  catch (DmlException e)  {
        System.debug(e.getMessage());
    }

Can I still use the Test code which Jesse included, or does it actually have to be re-written just to account for an Upsert instead of an Insert ?

Thank you again for all of your effort and time.

5
  • Hiring_Manager__c is a multi picklist? Mar 18 '13 at 19:17
  • No, it's a text area field which is being populated by a multiselect selectlist in a VF page. Jesse - You've helped me in the past. I re-registered here so I could log in properly. Thank you very much.
    – Zoom_v
    Mar 18 '13 at 19:31
  • Is the intention here to provide a junction record in the system between a User and a Position and indicate the User's role in that interview? Do [John, Stacy, Robert] have User records in the org? Are the values in the field just the first names as sampled in your question?
    – Mark Pond
    Mar 18 '13 at 19:34
  • Ah, that is no problem. Glad to hear I could help. I like figuring out the answers to these questions. I find it fun. Anyway, if you're multi-select like <apex:selectList multiselect="true">, I would assume you are generating SelectOption from a set of user records with the new SelectOption(Id, Name). If that is the case, you should still be able to use my reference below, although you may want to cast the hiringPosition variable as an ID rather than a String. Mar 18 '13 at 19:37
  • Thank you Mark - No - I'm not trying to create a junction record here. I only want to create a child record to the record being saved. I used the example here purely for the functionality of automatically creating a child record upon the Saving a record. In reality, the values of the multi-value field will have no type of reference to a standard SF object such as a User record etc. The values might as well be red,blue,green. And I would want to create a new record for each one of those colors.Also ftr:The choices of the mult-value field are not static. There could be 2 or 25 values in it.
    – Zoom_v
    Mar 18 '13 at 19:44
4

Multi-select picklists are stored as value1;value2;value3;etc. Knowing that, you can get a List of these values using the String split() method. You can also view this string splitting example. To access it, you would then tweak your code as:

trigger AutoCreateInterviewer on Position__c (after insert) {
    List<Interviewer__c> interviewers = new List<Interviewer__c>();

    //For each position processed by the trigger, add a new  

    //interviewer record for the specified hiring manager.  

    //Note that Trigger.New is a list of all the new positions  

    //that are being created.  

    for (Position__c newPosition: Trigger.New) {
        if (newPosition.Hiring_Manager__c != null) {
            // split out the multi-select picklist using the semicolon delimiter
            for(String hiringManager: newPosition.Hiring_Manager__c.split(';')){
                interviewers.add(new Interviewer__c(
                        Name = '1',
                        Position__c = newPosition.Id,
                        Employee__c = (Id)hiringManager,
                        Role__c = 'Managerial'));
            }
        }
    }
    insert interviewers;
}

@isTest
public with sharing class AutoCreateInterviewerTriggerTest {

    static testMethod void testGetAdvisor() {
        // First, set up your test User.
        User testUser = generateTestUser();

        // Generate your position but don't perform DML yet
        Position__c pos = new Position(Hiring_Manager__c = testUser.Id);

        // Start your test and insert your position
        Test.startTest();
        insert pos;
        Test.stopTest();

        // Get the interviewers from the DB to ensure they were created
        List<Interviewer__c> interviewers = [SELECT
                                                 Id
                                             FROM
                                                 Interviewer__c
                                             WHERE
                                                 Position__c = :pos.Id
        ];

        // There should be 1 interviewer because only one user ID was provided
        System.assert(1, interviewers.size(), 'One interviewer object is expected');
    }

    private User generateTestUser(){
        // We use the System Admin profile because it will always be there
        Profile sysAdmin = [SELECT 
                               Id 
                            FROM 
                               Profile 
                            WHERE 
                               Name = 'System Administrator'
                            LIMIT 1
        ];

        // Generate the user
        User newUser = new User(
            UserName = 'unit.tester@example.com',
            LastName = 'Test',
            FirstName = 'Jane',
            Email = 'unit.tester@example.com',
            phone = '555-555-5555',
            MobilePhone = '555-555-5554',
            Street = '123 Fake Street',
            City = 'Los Angeles',
            State = 'CA',
            PostalCode = '12345',
            CommunityNickName = 'unit.test',
            Alias = 'abcd',
            ProfileId = sysAdmin.Id,
            emailencodingkey = 'UTF-8',
            languagelocalekey = 'en_US',
            localesidkey = 'en_US',
            timezonesidkey = 'America/Los_Angeles'
        );

        // Insert that user
        insert user;

        return user;
    }
}
3
  • Thanks Jesse !!! Yes, you are right about the methods to generate SelectOption.Could you do me two more things? Can you show me how it would work as an Upsert if I use Hiring_Manager__c as the external iD ? And could you show me what test I'll need on that ? I haven't gotten to that part yet on Dev 501. I know I'm asking a lot here. I feel terrible asking this much. I really appreciate the time and effort. You've always been incredibly helpful.
    – Zoom_v
    Mar 18 '13 at 20:22
  • I added a test class with comments. It may or may not work, either way it will get your close. Also, my previous example should work for a list of Ids. I did make one small change just to make sure it as cast as an Id either way. Mar 18 '13 at 20:56
  • Wow - that is just awesome Jesse. I now have to convert it to an Upsert instead of an Insert, so I edited my original post to show what I think may be the necessary coding. I put an "UPDATE" in the post to show where the suggestions are at. If you can take a look at it and just tell me if I'm right I would be very grateful.
    – Zoom_v
    Mar 19 '13 at 15:22

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.