1

Could you help me find the problem with my custom Trigger? In a nutshell, I would like a picklist field called “Housekeeping_Status__c” to be updated to ‘Clean’ when the Account Id on one object (Housekeeping__c), is the exact account Id on another object (Property_Rate__c). Each object is unrelated but both share the same parent Account. This trigger should run (after insert, after update).

I should also mention that I have a second Housekeeping__c trigger (“Before insert, before update”) which populates the Account__r.Id on the Housekeeping__c record. I have no problem with this trigger.

Here is the broken code:

trigger setToClean on Housekeeping__c (after insert, after update)
{

     for (Housekeeping__c housekeeping : Trigger.new)
     {
           String houseaccount = housekeeping.Account__r.Id;

           List<Property_Rate__c> findRates = [SELECT Id FROM Property_Rate__c WHERE Account__r.Id = :houseaccount];

           for (Property_Rate__c currentRate : findRates)
           {
               currentRate.Housekeeping_Status__c = ‘Cleaned';
           }

     }
}
  • What's the problem you are facing? anyway you are not retrieving the field Housekeeping_Status__c even you are trying to access it in the trigger. – highfive May 27 '15 at 4:10
  • The problem is that the Housekeeping_Status__c on each of the Property_Rate__c objects is not updating. I should clarify that the Housekeeping_Status__c is a field within Property_Rate__c. – Alex Brigham May 27 '15 at 4:14
  • Okay, I've tried adding Housekeeping_Status__c into the findRates SOQL query. The Housekeeping_Status__c is still not updating. – Alex Brigham May 27 '15 at 4:21
2

UPDATE : Applied @snehakem suggestion

You are assigning the new value for the field but not updating the records. Just perform required DML.

trigger setToClean on Housekeeping__c (after insert, after update)
{
    List<Property_Rate__c> updatedPropertyList = new List<Property_Rate__c>();
    Set<String> accountIds = new Set<String>();

    for(Housekeeping__c housekeeping : Trigger.new){
        accountIds.add(housekeeping.Account__c);
    }

    List<Property_Rate__c> findRates = [SELECT Id, Housekeeping_Status__c FROM Property_Rate__c WHERE Account__r.Id IN :accountIds];

    for (Property_Rate__c currentRate : findRates)
    {
       currentRate.Housekeeping_Status__c = 'Cleaned';
       updatedPropertyList.add(currentRate);
    }

    update updatedPropertyList;  // This is what you are missing     
}

NOTE: This suggestion(not compiled and tested) is just for resolving your field not updating issue. Addition to that have a look at for the code if it's satisfying your requirement (I feel like you need some conditional statement).
Also note that it's not a good idea to have multiple triggers on same object as in documentations.

| improve this answer | |
  • Thanks highfive. I got the following error message when attempting to update the a Property_Rate__c record: Apex trigger setToClean caused an unexpected exception, contact your administrator: setToClean: System.LimitException: Too many DML rows: 10001 Any thoughts? – Alex Brigham May 27 '15 at 4:44
  • You never query inside for loop. Also you cant access parent fields like housekeeping.Account__r.Id this as it comes from trigger.New, Instead you can directly use housekeeping.Account__c – snehakem May 27 '15 at 4:47
  • You will not put update statements inside for loops, have a look at my code again. @snehakem agreed and I've updated the answer – highfive May 27 '15 at 4:54
  • But still you query inside for loop. I think thats not a bulkified code. Look at my answer. – snehakem May 27 '15 at 5:03
0

Try this,

trigger setToClean on Housekeeping__c (after insert, after update)

    List<Property_Rate__c> listToBeUpdated = new List<Property_Rate__c>();
        Set<Id> setAccId = new Set<Id>();

         for (Housekeeping__c housekeeping : Trigger.new)
         {
            setAccId.add(housekeeping.Account__c);
         }

         Map<Id,Property_Rate__c> mapAccIdProperty = new ap<Id,Property_Rate__c>();//Query outside for loop

         for(Property_Rate__c p :[SELECT Id,Account__c FROM Property_Rate__c WHERE Account__c = :setAccId]){
            mapAccIdProperty.put(p.Account__c,p);
         }
         for (Housekeeping__c housekeeping : Trigger.new)
         {
           if(housekeeping.Account__c!=null && mapAccIdProperty.keyset().contains(housekeeping.Account__c)){
                mapAccIdProperty.get(housekeeping.Account__c).Housekeeping_Status__c = ‘Cleaned';
                listToBeUpdated.add(mapAccIdProperty.get(housekeeping.Account__c));
           }   

         }
     if(listToBeUpdated.size()>0){
        update listToBeUpdated;    
     }
    }
| improve this answer | |
  • 1
    Thank you both for taking the time to help! Snehakem, I first tried your solution. For the first time, the trigger worked! But it only updated one of the records attached to the account. Highfive, I tried your updated solution and all associated records were updated! I will have to look through documentation to better understand the modifications that you made. Thank you both once again! Alex – Alex Brigham May 27 '15 at 5:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.