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
Zach DelacroixZach Delacroix 

Need help with Bulkification

Hi Guys!

Newbie here and I need someone who can help me bulkify my code. I've been struggling with it so I decided to post it :)

Below is My scenario:

User-added image

Job Record is associated to Account, the Account also have related list called Rate Cards.
As you can see, both Objects are tied to account and both have fields Type and Hourly Rate.

My Task is to Copy the Hourly Rate of the Rate Card in the Associated account that has the same type as the Job. (See Image Above)

I was able to do it with the Code below.
 
trigger UpdateHourlyRate on Job__c (Before insert, Before update) {
    
    Set<Id> AccID = new Set<Id>();

    Map<String,Rate_card__c> RateCardMap = new Map<String,Rate_card__c>();
    
    for (Job__c Job: Trigger.new){AccID.add(Job.Account__c);}
    
    For(Rate_Card__c RateCard : [SELECT Id, Hourly_Rate__c, Account__c, Type__c 
                                 FROM Rate_card__c 
                                 WHERE Account__c IN: AccID]){

                                     RateCardMap.put(RateCard.Account__c + RateCard.Type__c, RateCard);
                                 }
    
    For (Job__c Jobs: Trigger.new ){

        Jobs.Hourly_Rate__c = RateCardMap.get(Jobs.Account__c + Jobs.Type__c).Hourly_Rate__c;
    }
}

However, I know that this one is not bulkified and I was getting a lots of Error when I try bulkify it. I tried adding list and Updating the List (Like some of the videos I've watched and Tests I created) but no Luck.

Can someone please guide me how to bulkify my code? what are the best practice for this? :)

Thanks in advance!

\m/
Best Answer chosen by Zach Delacroix
sandeep sankhlasandeep sankhla
Hi Zach,

you can first check if that map contains that key or not else it will throw error..

like

if(RateCardMap.containskey(Jobs.Account__c + Jobs.Type__c))
        {
also if all used fields are mandatory then its fine else you need to first do a nul check and then continue..

Please check with both of these and let me know if it solves your issue..

your trigger seems good not major isue..it is bulkfield also, you just need to so some null chck thats it..

P.S. If my answer helps you to solve your problem please mark it as best answer. It will help other to find best answer.

Thanks,
Sandeep
Salesforce Certified Developer 

All Answers

sandeep sankhlasandeep sankhla
Hi Zach,

your req is whenever a job record is inserted or updated then you need to find its account and then you will find it related rate cards and then match the type of the job and update these 2 fields from job to rate cards

please confirm so ic an help you out

Thanks
Sandeep
PratikPratik (Salesforce Developers) 
Hi Zach,

What error you are facing?

Here are the guidelines for bulkifying trigger:
http://blog.jeffdouglas.com/2009/04/20/writing-bulk-triggers-for-salesforce/

Thanks,
Pratik
sandeep sankhlasandeep sankhla
Hi Zach,

you can first check if that map contains that key or not else it will throw error..

like

if(RateCardMap.containskey(Jobs.Account__c + Jobs.Type__c))
        {
also if all used fields are mandatory then its fine else you need to first do a nul check and then continue..

Please check with both of these and let me know if it solves your issue..

your trigger seems good not major isue..it is bulkfield also, you just need to so some null chck thats it..

P.S. If my answer helps you to solve your problem please mark it as best answer. It will help other to find best answer.

Thanks,
Sandeep
Salesforce Certified Developer 
This was selected as the best answer
Zach DelacroixZach Delacroix
Thanks Guys!

I've tried the code below before because I thougt that it's not bulkified.

 
trigger UpdateHourlyRate on Job__c (Before insert, Before update) {
Set<Id> AccID = new Set<Id>();
Map<String,Rate_card__c> RateCardMap = new Map<String,Rate_card__c>();

for (Job__c Job: Trigger.new){AccID.add(Job.Account__c);}

For(Rate_Card__c RateCard : [SELECT Id, Hourly_Rate__c, Account__c, Type__c
                                             FROM Rate_card__c
                                             WHERE Account__c IN: AccID]){

                            RateCardMap.put(RateCard.Account__c + RateCard.Type__c, RateCard); }

//I Though of having this so I can use DML statement.
//Not Sure when to really do this approach?
Map<String,Job__c> JobsToSave = new Map<String,Job__c>();

For (Job__c Jobs: Trigger.new ){

                 //This below was sandeep's suggestion and it helps with the code :)
                 //if(RateCardMap.containsKey(Jobs.Account__c+Jobs.Type__c)){

                 Jobs.Hourly_Rate__c = RateCardMap.get(Jobs.Account__c + Jobs.Type__c).Hourly_Rate__c;

                 JobsToSave.put(Jobs.Id, Jobs);
                  //}
} if(JobsToSave != Null) Update JobsToSave.values();
}


With This code, I get the Error below.


User-added image


Below is my final Code which works great even in Bulk.
 
trigger UpdateHourlyRate on Job__c (Before insert, Before update) {

Set<Id> AccID = new Set<Id>();
Map<String,Rate_card__c> RateCardMap = new Map<String,Rate_card__c>();

     For (Job__c Job: Trigger.new){AccID.add(Job.Account__c);}

     For(Rate_Card__c RateCard : [SELECT Id, Hourly_Rate__c, Account__c, Type__c
                                                  FROM Rate_card__c
                                                  WHERE Account__c IN: AccID]){

                                                 RateCardMap.put(RateCard.Account__c + RateCard.Type__c, RateCard); }

     For (Job__c Jobs: Trigger.new ){

          if(RateCardMap.containsKey(Jobs.Account__c+Jobs.Type__c)){
               Jobs.Hourly_Rate__c = RateCardMap.get(Jobs.Account__c + Jobs.Type__c).Hourly_Rate__c;
          }
      }
}

So this one is already bulkified and there's no need to add a DML statement?

Thanks a lot for the answers :)

-Zach
sandeep sankhlasandeep sankhla
Hi Zach,

There is no need of DML statememnts when your trigger fires on Before events...it will automatically do the job as before means , before committing to database you are doing the changes..so DML not required on before events..

Yes, we need to always check containsKey if using map and getting avlue from map..because if map doesnot contain that key then null.get will throw error..so we need to do all these blank and null checks in our code..

P.S. If my answer helps you to solve your problem please mark it as best answer. It will help other to find best answer.

Thanks,
Sandeep
Salesforce Certified Developer 
Zach DelacroixZach Delacroix
Awesome! Thank you for the Help Sandeep!

And for Pratik for providing the Blog for this :)
PratikPratik (Salesforce Developers) 
Glad it helped Zach!

Thanks,
Pratik