You need to sign in to do that
Don't have an account?

A tough trigger to bulkify
Hi
I am getting the hang of these but need to bulkify this trigger. Essentially it takes a course_application and checks to see if the course applicant is a campaign member. There are a couple of many to many relationships so suspect that I will need to use a map with a list? If a campaign member exists it updates it, if not create a new one. Managed to do this by iterating through the course apps and building a list then checking the size of the list. However, It also doesn't take into account any new course_applications created during the fioring of the trigger. Any help appreciated
les
List<CampaignMember> cmbadd = new List<CampaignMember>(); List<CampaignMember> cmbupdate = new List<CampaignMember>(); for(Course_Application__c c:Trigger.new) { List<CampaignMember> cammem =[select id from CampaignMember where CampaignMember.contactid =:c.Course_Applicant_del__c AND CampaignMember.CampaignId=:c.PullCampaignID__c]; if(cammem.size() == 0) { CampaignMember cmb = new CampaignMember(contactId=c.Course_Applicant_del__c, CampaignId=c.PullCampaignID__c, status=c.status__c); cmbadd.add(cmb); } Else { CampaignMember cmbup = cammem[0]; cmbup.status=c.status__c; cmbupdate.add(cmbup); } } Database.insert(cmbadd); Database.update(cmbupdate);
Les,
Give this a try:
If this helps, please mark it as a solution, and give kudos (click on the star) if you think I deserve them. Thanks!
-Glyn Anderson
Certified Salesforce Developer | Certified Salesforce Administrator
thanks, there was one typo but fixed it and yes it works.
However, when I deploy to production I get too many SOQL queries, this is the full code which I'm pretty sure is now fine.
but I also have another triggger that fires on the same object, could this cause the problem? If so here's the code.
Les,
I'm not seeing anything obvious in the two triggers that would cause the "Too Many SOQL Queries" error; but keep in mind that these triggers also insert or update CampaignMembers, Course__c and myOrder__c objects, so those triggers will run, too. And some trigger might run twice if there are any Workflow field updates happening. You'll have to look at the triggers on those other objects to figure out if they might be causing the problem.
-Glyn
Les,
You didn't ask for this, but I've made a couple of changes to your second trigger. These changes will make it easier to get code coverage with your test methods.
The first change is to have one for loop that iterates either trigger.new or trigger.old based on whether it's a delete trigger. With a single loop, the code is covered by an insert or update, without having to do a separate delete test. (You may want to anyway, to assert functionality).
The second change is to assign the Payment_Status__c field using the ternary operator '?:' (also called a conditional evaluation operator). This reduces three if statements into a single statement that is covered no matter which condition is true. You don't have to write three different tests to cover the code. (Again, you may want to, to test functionality - but you won't have to just to cover the code.)
I've also reformatted bits of the code. That's just to help me read the code and because I'm **bleep**-retentive that way. I don't mean to foist my particular coding style on you. I hope you find this useful.
-Glyn
Glyn
Thanks for your help on this one, greatly appreciated.
I've looked at this code again and it seems to me that there is a query in a loop in the later part of the code?
I also have a similar trigger that I think is doing similar, see attached. Do these need bulkifying further?
Les,
When you use a SOQL query as the iterable object in a for loop, the query isn't "in" the for loop - the query is only performed once and the loop iterates over the result. You only need to worry about queries that are in the body of the for loop, where they will be performed once for every iteration of the loop.
As for the other trigger, I gave it a quick look and don't see any obvious problems vis-a-vis bulk operation.
-Glyn
ok, so if I write a test script that, for example, creates objects in a sequence that fires & re-fires triggers, could the error be that the test script has exceeded to SOQL limit rather than the code itself exceeding the limit?
Yes, it's easy to write a test method that does too much, particularly if you're firing the trigger many times. A better design is to split the test up as much as possible, testing one case in each test method. It helps to write a small utility routine that all your test methods call to set up test records common to all tests.
Also, be sure to use startTest/stopTest around the actual test in your test method. Everything that runs between startTest and stopTest has its own limits, so you can tell whether the code you're testing is exceeding the limits (separate from what your test code is doing).
For example:
Note that you can only use startTest/stopTest once per test method.
-Glyn