0

first SSE post :)

I wrote a trigger that worked just fine all on its own, but I wanted to see how to put the functioning part of the trigger into a class, and then get the trigger to simply call the class. The class both updates a record and creates a new detail record for the record that is updated. I've written both the trigger and class, and both compile just fine. But the record is not updating and the detail record is not being created. Basically, nothing is happening.
Here's the trigger:

trigger CreateFlea on Pet__c(before update) {
    for (Pet__c x: Trigger.new) {
        CreateFleaClass.CreateFleaMethod();
    }
}

So it's just calling this class on every update of any Pet_c record.
Now here's the class:

public class CreateFleaClass {
    public static void CreateFleaMethod() {
        Pet__c x = new Pet__c();
        if (x.Breed__c == 'Irish Setter') {
            x.Age__c = 4;
            x.Color__c = 'Cerulean';
            ID PetID = x.Id;
            Flea__c newflea = new Flea__c(
                Name = 'Jimmy',
                Pet__c = PetID);
            insert newflea;
        }
    }
}

But when I set x.Breed__c == 'Irish Setter', nothing happens. It worked just fine when it was all in a trigger, as below. Any ideas? Thanks folks.

trigger CreateFlea on Pet__c(before update) {
    for (Pet__c x: Trigger.new) {
        if (x.Breed__c == 'Irish Setter') {
            x.Age__c = 4;
            x.Color__c = 'Cerulean';
            ID PetID = x.Id;
            Flea__c newflea = new Flea__c(
                Name = 'Jimmy',
                Pet__c = PetID);
            insert newflea;
        }
    }
}
  • Welcome to SFSE and apex coding. – Santanu Boral Jul 8 '16 at 0:48
  • why are you setting the Pet's Trigger.new age and color on beforeUpdate and what does that have to do with creating Fleas? As a general rule, related objects should be created in after triggers. – cropredy Jul 8 '16 at 3:27
  • Ha, @cropredy, it has nothing to do with it, I'm not actually trying to track real fleas in a SF org... – number41 Jul 8 '16 at 18:14
  • @JSF Is my answer solved your problem then please mark. – Santanu Boral Jul 9 '16 at 15:46
5

You can change the code as follows: Pass Trigger.old and Trigger.new to the method, so that you can handle every logic in the method.

Trigger

trigger CreateFlea on Pet__c (before update){
CreateFleaClass.CreateFleaMethod(Trigger.old,Trigger.new);
}

CreateFleaClass

public class CreateFleaClass {
public static void CreateFleaMethod(List<Pet__c> oldList, List<Pet__c> newList)
{
      List<Flea__c> insertList = new List<Flea__c>();
      for (Pet__c x: newList)
      {
           if(x.Breed__c == 'Irish Setter')
           {         
                x.Age__c = 4;
                x.Color__c = 'Cerulean';
                ID PetID = x.Id;

                Flea__c newflea = new Flea__c(
                Name = 'Jimmy',
                Pet__c = PetID);
                insertList.add(newflea); 
            }
    }
    if(insertList.size()>0)
        insert insertList;
}
}
  • 2
    JSF: Note that Santanu has done two important things to your code here. He changed it so that the Trigger.old and Trigger.new lists get passed as parameters, and changed your CreateFleaMethod to handle those parameters, yes. But he also bulkified the insert of the Fleas - they're created in memory and added to a List<Flea_c> and then inserted all at once at the end with a single DML statement, rather than inserting them on each pass through the loop that processes Trigger.old. – Thomas Taylor Jul 8 '16 at 0:43
  • @ThomasTaylor you are correct – Santanu Boral Jul 8 '16 at 0:45
  • Thanks for this! So I don't quite understand the logic behind having two lists (old and new). I understand bulkifying it with lists, but why can't I just generate a single list of all Pet__c records and create a Flea__c record for each? Thanks again – number41 Jul 15 '16 at 14:41
  • @JSF for your purpose old list is sufficient. But here I just wanted to show you how you can delegate old and new list to the class and handle as per your requirement. Please mark this answer if your purpose is resolved. – Santanu Boral Jul 15 '16 at 14:58
  • Thanks again, but this code causes an exception error any time one updates a record, any idea why? "Error:Apex trigger CreateFlea caused an unexpected exception, contact your administrator: CreateFlea: execution of BeforeUpdate caused by: System.FinalException: Record is read-only: Class.CreateFleaClass.CreateFleaMethod: line 9, column 1 – number41 Aug 3 '16 at 18:38
0

I was able to fix it - just passed Trigger.new to this:

public class CreateFleaClass {
public static void CreateFleaMethod(List<Pet__c> PetList)
{
      List<Flea__c> FleaList = new List<Flea__c>();

      for (Pet__c x: PetList)
      {
           if(x.Breed__c == 'Irish Setter')
           {         
                x.Age__c = 4;
                x.Color__c = 'Cerulean';
                ID PetID = x.Id;

                Flea__c newflea = new Flea__c(
                Name = 'Jimmy',
                Pet__c = PetID);
                FleaList.add(newflea); 
            }
    }
    insert FleaList;
}
  • Same thing I have updated in my code earlier – Santanu Boral Aug 4 '16 at 2:00
  • One thing I don't understand is why List<Pet__c> PetList is put in parentheses immediately after CreateFleaMethod. What do those parentheses indicate? Why can't the list be created when the Flea list is created? – number41 Aug 4 '16 at 19:42
  • With that PetList in parenthesis you can pass Trigger.new to this method. Also this method is generic, so it can be called from trigger or any other methods – Santanu Boral Aug 4 '16 at 21:12

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.