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
Brendon Wilkinson 59Brendon Wilkinson 59 

Issue with Trigger to relate a record to a custom object

I followed the instructions here: https://support.zendesk.com/hc/en-us/articles/203660056-Salesforce-Creating-custom-links-in-Salesforce-Zendesk-Ticket#creating-a-trigger

This trigger works except that row 7 assumes that at least 1 record is found. If not it throws an error 'List has no rows for assignment to SObject' if there is not a record available for assignment. 

I found this answer: https://help.salesforce.com/articleView?id=000159853&type=1

And have tried to incorporate it but I keep getting errors. Can anyone give some guidance on how to rewrite this? 

User-added image
Best Answer chosen by Brendon Wilkinson 59
Damon ShawDamon Shaw
from what I can tell your update to the code wasn't quite complete

firstly we create a set of the gig names
then we get a list of gigs using those names (I hope they are unique!)
we then put those gigs into a map using their names
finally we loop over the resource requests, look at the gig name and use that to look up the gig from the map and set the Id if it's wrong

I've also added a quick null check incase we couldn't find a gig with the name listed on the resource request
 
trigger RelateResourceRequestToGig on Resource_Request__c (before insert, before update)
{
    //get all of the gig names that are in the trigger
    Set<String> gigNames = new Set<String>();
    for(Resource_Request__c z :Trigger.new){
        gigNames.add(z.GigID_Text__c);
    }
    
    //find all related gigs
    List<Gig__c> gigs = [SELECT Id, Name FROM Gig__c WHERE Name IN :gigNames];
    if(gigs.size() > 0){
        //put the gigs in a map using their name
        Map<String, Gig__c> gigsByName = new Map<String, Gig__c>();
        for(Gig__c g :gigs){
            gigsByName.put(g.Name, g);
        }
        //loop over the tickets in the trigger
        for(Resource_Request__c z :Trigger.new){
            // find the gig using the id linked to the resource request
            Gig__c gig = gigsByName.get(z.GigID_Text__c);

            //if the gig Id linked to the resource request does not match the Id of the gig match, update the Id
            if(gig != null){
                if(z.Gig__c != gig.Id){
                    z.Gig__c = gig.Id;
                }
            }            
        }
    }
}

 

All Answers

Damon ShawDamon Shaw
Hi Brendon,

I've had to type out your code from the image, sorry if there are typos

firstly you should bulkify your trigger, you may have a specific use case at the moment but who knows what happens in the future and if the trigger has to process more than 1 record at a time things will soon crash,

hopefully this should help you out
trigger RelateOpportunity on Zendesk__Zendesk_Ticket__c (before insert, before update)
{
   
    //get all of the opportunity names that are in the trigger
    Set<String> opnames = new Set<String>();
    for(Zendesk__Zendesk_Ticket__c z :Trigger.new){
        opnames.add(z.Opportunity_Name__c);
    }

    //find all related opportiunities
    List<Opportunity> opps = [SELECT Id, Name FROM Opportunity WHERE Name IN :opnames];
    if(opps.size() > 0){

        //put the opportunites in a map using their name
        Map<String, Opportunity> opprotunitiesByName = new Map<String, Opportunity>();
        for(Opportunity o :opps){
            opprotunitiesByName.put(o.Name, o.Id);
        }

        //loop over the tickets in the trigger
        for(Zendesk__Zendesk_Ticket__c z :Trigger.new){
            // find the opportunity using the name linked to the ticket
            Opportunity opp  = opprotunitiesByName.get(z.Opportunity_Name__c);

            //if the opportunity Id linked to the ticket does not match the Id of the opportunity match by name, update the Id
            if(z.Zendesk__Opportunity__c != opp.Id){
                z.Zendesk__Opportunity__c = opp.Id;
            }
        }
    }
}

 
Brendon Wilkinson 59Brendon Wilkinson 59
Thanks Damon for the response. I really appreciate it.

In fact I have been trying to use the template to relate one custom object to another (utilizing the structure sent previously) however when I converted this I am getting an error>
trigger RelateResourceRequestToGig on Resource_Request__c (before insert, before update)
{
    //get all of the opportunity names that are in the trigger
    Set<String> opnames = new Set<String>();
    for(Resource_Request__c z :Trigger.new){
        opnames.add(z.GigID_Text__c);
    }
    
    //find all related gigs
    List<Gig__c> gigs = [SELECT Id, Name FROM Gig__c WHERE GigID__c IN :opnames];
    if(gigs.size() > 0){
        //put the gigs in a map using their name
        Map<String, Gig__c> gigsByName = new Map<String, Gig__C>();
        for(Gig__c o :gigs){
            gigsByName.put(o.Name, o.Id);
        }
        //loop over the tickets in the trigger
        for(Resource_Request__c z :Trigger.new){
            // find the gig using the id linked to the resource request
            Gig__c gig = gigsByName.get(z.Gig__c);

            //if the gig Id linked to the resource request does not match the Id of the gig match, update the Id
            if(z.Gig__c != gig.Id){
                z.Gig__c = gig.Id;
            }
        }
    }
}

Error: Compile Error: Illegal assignment from Map<String,Id> to Map<String,Gig__c> at line 13 column 29

(Map<String, Gig__c> gigsByName = new Map<String, Gig__C>();)

Do you know how to resolve this issue?

Thanks,
Damon ShawDamon Shaw
Hi Brendon,

You were really close, the issue was at line 15 where you are trying to put a String and Id into a String and Gig__c map, just change that to gigsByName.put(o.Name, o); and it should work better
Brendon Wilkinson 59Brendon Wilkinson 59
Thanks the trigger saved but I went to create a new Resource Request with a value populated in GigID_Text__c and got the below error. It will let me delete that field but it will not let me add it. Any thoughts?

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger RelateResourceRequestToGig caused an unexpected exception, contact your administrator: RelateResourceRequestToGig: execution of BeforeUpdate caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.RelateResourceRequestToGig: line 23, column 1
Damon ShawDamon Shaw
from what I can tell your update to the code wasn't quite complete

firstly we create a set of the gig names
then we get a list of gigs using those names (I hope they are unique!)
we then put those gigs into a map using their names
finally we loop over the resource requests, look at the gig name and use that to look up the gig from the map and set the Id if it's wrong

I've also added a quick null check incase we couldn't find a gig with the name listed on the resource request
 
trigger RelateResourceRequestToGig on Resource_Request__c (before insert, before update)
{
    //get all of the gig names that are in the trigger
    Set<String> gigNames = new Set<String>();
    for(Resource_Request__c z :Trigger.new){
        gigNames.add(z.GigID_Text__c);
    }
    
    //find all related gigs
    List<Gig__c> gigs = [SELECT Id, Name FROM Gig__c WHERE Name IN :gigNames];
    if(gigs.size() > 0){
        //put the gigs in a map using their name
        Map<String, Gig__c> gigsByName = new Map<String, Gig__c>();
        for(Gig__c g :gigs){
            gigsByName.put(g.Name, g);
        }
        //loop over the tickets in the trigger
        for(Resource_Request__c z :Trigger.new){
            // find the gig using the id linked to the resource request
            Gig__c gig = gigsByName.get(z.GigID_Text__c);

            //if the gig Id linked to the resource request does not match the Id of the gig match, update the Id
            if(gig != null){
                if(z.Gig__c != gig.Id){
                    z.Gig__c = gig.Id;
                }
            }            
        }
    }
}

 
This was selected as the best answer
Brendon Wilkinson 59Brendon Wilkinson 59
Thank you so much! It worked