function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
DePlungeDePlunge 

Issue with Apex Trigger to copy CreatedById user to a Custom Lookup Field

HI, 

 

I'm pretty new to this APEX lark and am not sure if I'm doing this right, so any assistance would be greatly appreciated. 

 

I have written a trigger (adapted from one that I have found online). The triggers purpose is to (before update) map the OwnerId field to a custom User Lookup of my custom object Change_Request__c. 

 

TRIGGER DETAIL

 

 

 
trigger onChangeReqBeforeUpdate on Change_Request__c (before update) {
    
    Set<Id> ownerIds = new Set<Id>();
    Map<Id, List<Change_Request__c>> owner = new Map<Id, List<Change_Request__c>>();
        for(Change_Request__c cr : trigger.new){
            ownerIds.add(cr.OwnerId);
            List<Change_Request__c> crq = new List<Change_Request__c>();
            if(owner.containsKey(cr.OwnerId)) crq = owner.get(cr.OwnerId);
               crq.add(cr);
               owner.put(cr.OwnerId, crq);
            } 
        for(User u : [SELECT Id FROM User WHERE Id IN :ownerIds]){
        for(Change_Request__c cr : owner.get(u.id)){
        
        cr.Assigned_To__c = u.Id;
        }
    }
    
}

 

Now this trigger works as expected. With this in mind I wanted to create a similar trigger that runs 'before insert' only. I copied the above code to a new trigger (below) on the same object. However this time I wish to map the CreatedById field to a custom User Lookup field. 

The new trigger however doesn't work, but I have no idea why... 

 
trigger onChangeReqBeforeInsert on Change_Request__c (before insert) {

    Set<Id> createdbyIds = new Set<Id>();
    Map<Id, List<Change_Request__c>> createdby = new Map<Id, List<Change_Request__c>>();

        for(Change_Request__c cr : trigger.new){
            createdbyIds.add(cr.CreatedById);
            List<Change_Request__c> crq = new List<Change_Request__c>();

            if(createdby.containsKey(cr.CreatedById)) crq = createdby.get(cr.CreatedById);
               crq.add(cr);
               createdby.put(cr.CreatedById, crq);
            } 

        for(User u : [SELECT Id FROM User WHERE Id IN :createdbyIds]){
        for(Change_Request__c cr : createdby.get(u.id)){
        
        cr.Requested_By__c = u.Id;

        }
    }
    
}

 

I would be most greaftul for some guidance in terms of writing test classes for this. 
Thanks in advance
Ben

 

 

myforcedotcommyforcedotcom

Hi Ben,

The reason your before insert trigger does not work is because the CreatedById is not populated until the record is added to the database. since you are at the before insert event that has not happened and your values are null.

 

 

DePlungeDePlunge

Hi Code the Cloud, 

 

Thanks for your reply, I did think that, so I changed ithe method to After Insert and got a Record is Read-Only error?

 

It's obviously not that simple but the object and field itself isn't read only, so not sure why it's returning that.

 

Any ideas 

 

 

Shashikant SharmaShashikant Sharma

Ther eason for it is that in before insert trigger you will get value for CreatedById as null so your trigger will never give you correct redult. You have to use after insert trigger for this. Like this

 

 

trigger onChangeReqBeforeInsert on Change_Request__c (after insert) {

    Set<Id> createdbyIds = new Set<Id>();
    Map<Id, List<Change_Request__c>> createdby = new Map<Id, List<Change_Request__c>>();

        for(Change_Request__c cr : trigger.new){
            createdbyIds.add(cr.CreatedById);
            List<Change_Request__c> crq = new List<Change_Request__c>();

            if(createdby.containsKey(cr.CreatedById)) crq = createdby.get(cr.CreatedById);
               crq.add(cr);
               createdby.put(cr.CreatedById, crq);
            } 
        List<Change_Request__c> listToUpdate = new List<Change_Request__c>();
        for(User u : [SELECT Id FROM User WHERE Id IN :createdbyIds]){
        for(Change_Request__c cr : createdby.get(u.id)){
        
        cr.Requested_By__c = u.Id;
        listToUpdate.add(cr);

        }
        
    }
    update listToUpdate;
    
}

 

 

 

This update will take you to update trigger unnecessary, so put a condition there using static variable seet his for more :

http://forceschool.blogspot.com/2011/05/writing-apex-trigger-issues-and_24.html

 

Second Way : Easiar one

You can try a tricky solution here just do this, 

 

trigger onChangeReqBeforeInsert on Change_Request__c (after insert) {

        List<Change_Request__c> listToUpdate = new List<Change_Request__c>();
        for(Change_Request__c cr : createdby.get(u.id)){
        listToUpdate.add(cr);
        }
        update listToUpdate;
    
    
}

 

 

 

 

DePlungeDePlunge

Hi Shashikant, 

 

Thanks for the solution. I will check it out when I have a spare 5 and get back to you. I must say my inexperience has got the better of me and I'm a bit stumped, I can not get wither of those to work. 

 

Instead I have deceided that for now I will update the custom look up with the Current User Id, it seems to work OK.

 

I will reveist this when I get a chance.

 

Thanks for all your time  


Cheers

 

Ben