0

I am writing a trigger for a custom object (Subscription__c), where I need to find other records of the same object that share a lookup to Contact (field name: Subscriber__c), and copy some information from the related record to the current record.

I have a working trigger but it is not bulkified due to having a SOQL query in the trigger loop. From reading other answers I think I need to use sets/maps to bulkify but not sure how to implement this.

Any advice would be much appreciated.

    trigger SubscriptionTrigger on Subscription__c (before insert, before update) {

    for (Subscription__c thisSub : Trigger.new ){

        //Search for Completed Subs with the Subscriber ID matching this sub's Subscriber ID. 
        List<Subscription__c> relatedSubs = [SELECT Id, Application_Status__c, No_of_Items__c, Subscriber__c, Subscription_Status__c FROM Subscription__c
                                             WHERE Application_Status__c='Completed' AND Subscriber__c =:thisSub.Subscriber__c ORDER BY CreatedDate DESC];

        system.debug('Related Sub 0: '+relatedSubs[0]);

        //Take the No of Items on the most recent one
        Decimal prevItems = relatedSubs[0].No_of_Items__c;

        //Save that number in Prev No Items on this Sub.
        thisSub.Prev_No_of_Items__c = prevItems;

    }

}

1 Answer 1

2

First you should create a set of id's of the subscribers:

Set<Id> subscribers = new Set<Id>();
for (Subscription__c sub : Trigger.new) subscribers.add(sub.Subscriber__c);

Then create a Map from the result:

Map<Id, Subscription__c> subs = new Map<Id, Subscription__c>();
for (Subscription__c sub : [SELECT Id, Application_Status__c, No_of_Items__c, Subscriber__c, Subscription_Status__c FROM Subscription__c
                                         WHERE Application_Status__c='Completed' AND Subscriber__c in :subscribers ORDER BY CreatedDate DESC]){
  if (!subs.containsKey(sub.Subscriber__c)) subs.put(sub.Subscriber__c, sub);
}

Then use this for your main loop:

for (Subscription__c sub : trigger.new){
  Subscription__c relatedSub = subs.get(sub.Subscriber__c);
  [...]
}
1
  • 1
    This seems to work fine (as did another answer using a map of <String, Integer> which has been deleted). Needed to add an if statement to handle situations where there is no matching subscription, so the main loop looks like this: for (Subscription__c sub : trigger.new){ if(subs.containsKey(sub.Subscriber__c)){ Subscription__c relatedSub = subs.get(sub.Subscriber__c); system.debug('relatedSub: '+relatedSub); sub.Prev_No_of_Items__c = relatedSub.No_of_Items__c; }
    – Nick
    Commented Feb 25, 2020 at 12:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .