0

I am getting this error Record is Read Only on my Before Update trigger... I know you get that error on an After Update when you try and change something, but not a Before Update.

trigger ytp_trigger_assignAdvisorToStudent on Student__c (before insert, before update) {

    /**
     * VARIABLES
     */
    // String ids for the male and female gender objects
    List<Gender__c> genderRecs = [SELECT id, Name FROM Gender__c];
    String maleGenderId = '';
    String femaleGenderId = '';
    for (Gender__c rec : genderRecs) {
        if (rec.Name == 'Male') { maleGenderId = rec.id; }
        else if (rec.Name == 'Female') { femaleGenderId = rec.id; } 
    }
    // Male and Female maps that will contain the coach's Id and their number of students
    Map<String, Integer> maleAdvisorsStudentCount = new Map<String, Integer>();
    Map<String, Integer> femaleAdvisorsStudentCount = new Map<String, Integer>();

    /**
     * QUERIES
     */
    // Query the database for coach ids and sort by ascending number of students assigned to them.
    List<AggregateResult> allAdvisorsStudentCount = [SELECT Advisor__c, count(Id) num_students FROM Student__c WHERE Advisor__c != '' GROUP BY Advisor__c ORDER BY count(Id) ASC]; 
    // Query the database for all male and female coaches, seperately
    List<Advisor__c> allMaleAdvisors = [SELECT id, Gender__c, OwnerId FROM Advisor__c WHERE Gender__c = :maleGenderId];
    List<Advisor__c> allFemaleAdvisors = [SELECT id, Gender__c, OwnerId FROM Advisor__c WHERE Gender__c = :femaleGenderId];

    /**
     * PREPARE COACH DATA
     */
    // Fill the maleAdvisorsStudentCount Map
    for (Advisor__c mc : allMaleAdvisors) {
        Boolean coachAddedToMap = false;
        // Loop through the allAdvisorsStudentCount array and find the current male coach's number of students
        for (AggregateResult acr : allAdvisorsStudentCount) {
            String coachId = (String)acr.get('Advisor__c');
            Integer numStudents = (Integer)acr.get('num_students');
            // If id's match, add the coach and the number of students to the maleAdvisorsStudentCount map
            if (mc.Id == coachId) {
                maleAdvisorsStudentCount.put(mc.id, numStudents);
                coachAddedToMap = true;
                break;
            }
        }
        // Coach not found in allAdvisorsStudentCount, add to maleAdvisorsStudentCount with value of '0'
        if (!coachAddedToMap) maleAdvisorsStudentCount.put(mc.Id, 0);
    }

    // Fill the femaleAdvisorsStudentCount Map
    for (Advisor__c fc : allFemaleAdvisors) {
        Boolean coachAddedToMap = false;
        // Loop through the allAdvisorsStudentCount array and find the current female coach's number of students
        for (AggregateResult acr : allAdvisorsStudentCount) {
            String coachId = (String)acr.get('Advisor__c');
            Integer numStudents = (Integer)acr.get('num_students');
            // If id's match, add the coach and the number of students to the femaleAdvisorsStudentCount map
            if (fc.Id == coachId) {
                femaleAdvisorsStudentCount.put(fc.id, numStudents);
                coachAddedToMap = true;
                break;
            }
        }
        // Coach not found in allAdvisorsStudentCount, add to femaleAdvisorsStudentCount map with value of '0'
        if (!coachAddedToMap) femaleAdvisorsStudentCount.put(fc.Id, 0);
    }

    /**
     * ASSIGN COACHES TO NEW STUDENTS
     */
    // Assign new students
    if (Trigger.isBefore && Trigger.isInsert) {
        for (Student__c newStudent: Trigger.New) {
            String minCoachKey = '';
            Integer minValue = 1000000;

            if (newStudent.advisorEligible__c == false) {
                return;
            } 

            if (newStudent.Gender__c == null) {
                newStudent.addError('\'Gender\' missing');
                return;
            }

            // Find the coach with the least amount of students
            if (newStudent.Gender__c == maleGenderId) { 
                // Male Student
                for (String coachKey : maleAdvisorsStudentCount.keySet()) {
                    Integer coachStudentCount = maleAdvisorsStudentCount.get(coachKey);
                    if (coachStudentCount < minValue) {
                        minCoachKey = coachKey;
                        minValue = coachStudentCount;

                    }
                } 
            } else if (newStudent.Gender__c == femaleGenderId) { 
                // Female Student 
                for (String coachKey : femaleAdvisorsStudentCount.keySet()) {
                    Integer coachStudentCount = femaleAdvisorsStudentCount.get(coachKey);
                    if (coachStudentCount < minValue) {
                        minCoachKey = coachKey;
                        minValue = coachStudentCount;
                    }
                }
            }

            // Assign coach
            newStudent.Advisor__c = minCoachKey;
            // Update Coach Maps
            if (newStudent.Gender__c == maleGenderId) {
                maleAdvisorsStudentCount.put(minCoachKey, minValue+1);
                // Change the newStudent's OwnerId to the Advisor's OwnerId
                for (Advisor__C advisor : allMaleAdvisors) {
                    if (advisor.id == minCoachKey) {
                        newStudent.OwnerId = advisor.OwnerId;
                    }
                }
            }
            else if (newStudent.Gender__c == femaleGenderId) {
                femaleAdvisorsStudentCount.put(minCoachKey, minValue+1);
                // Change the newStudent's OwnerId to the Advisor's OwnerId
                for (Advisor__C advisor : allFemaleAdvisors) {
                    if (advisor.id == minCoachKey) {
                        newStudent.OwnerId = advisor.OwnerId;
                    }
                }
            }
        }
    }

    // Assign Old Users
    if (Trigger.isBefore && Trigger.isUpdate) {
        for (Student__c oldStudent: Trigger.Old) {
            String minCoachKey = '';
            Integer minValue = 1000000;

            if (oldStudent.advisorEligible__c == false) {
                oldStudent.Advisor__c = null;
                return;
            } 

            if (oldStudent.Gender__c == null) {
                oldStudent.addError('\'Gender\' missing');
                return;
            }

            // Find the coach with the least amount of students
            if (oldStudent.Gender__c == maleGenderId) { 
                // Male Student
                for (String coachKey : maleAdvisorsStudentCount.keySet()) {
                    Integer coachStudentCount = maleAdvisorsStudentCount.get(coachKey);
                    if (coachStudentCount < minValue) {
                        minCoachKey = coachKey;
                        minValue = coachStudentCount;

                    }
                } 
            } else if (oldStudent.Gender__c == femaleGenderId) { 
                // Female Student 
                for (String coachKey : femaleAdvisorsStudentCount.keySet()) {
                    Integer coachStudentCount = femaleAdvisorsStudentCount.get(coachKey);
                    if (coachStudentCount < minValue) {
                        minCoachKey = coachKey;
                        minValue = coachStudentCount;
                    }
                }
            }

            // Assign coach
            oldStudent.Advisor__c = minCoachKey;
            // Update Coach Maps
            if (oldStudent.Gender__c == maleGenderId) {
                maleAdvisorsStudentCount.put(minCoachKey, minValue+1);
                // Change the newStudent's OwnerId to the Advisor's OwnerId
                for (Advisor__C advisor : allMaleAdvisors) {
                    if (advisor.id == minCoachKey) {
                        oldStudent.OwnerId = advisor.OwnerId;
                    }
                }
            }
            else if (oldStudent.Gender__c == femaleGenderId) {
                femaleAdvisorsStudentCount.put(minCoachKey, minValue+1);
                // Change the newStudent's OwnerId to the Advisor's OwnerId
                for (Advisor__C advisor : allFemaleAdvisors) {
                    if (advisor.id == minCoachKey) {
                        oldStudent.OwnerId = advisor.OwnerId;
                    }
                }
            }
        }
    }
}

This code works fine on the Before Insert part, but not the Before Update. What am I doing wrong? Isn't the record suppose to be editable in a Before Update?

2

You can only update records in trigger.new. You need to iterate over that collection rather than trigger.old for any field updates you wish to make in your before update trigger.

3
  • I thought Trigger.New corresponded to new record and Trigger.Old corresponded to old records? What does the New and Old actually distinguish?
    – BlondeSwan
    Mar 19 '19 at 17:29
  • Yes that is correct. You can't update what the records were, only what they will become.
    – Adrian Larson
    Mar 19 '19 at 18:01
  • To clarify, "old" represents the records as they were before the initiating DML operation (e.g. insert, update etc.) whilst "new" represents these same records with their updated state. This state may be updated further by your trigger, other triggers not yet executed and any flows configured for their object type.
    – Phil W
    Mar 19 '19 at 23: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.