+ Start a Discussion
brielea1984brielea1984 

Help Writing a "Most Recent" Record Trigger

I have a parent object: Cycle__c

The child object is: Sessions__c

 

Each Cycle__c has multiple sessions. I have put a lookup field, Latest_Session__c, that I want populated with the most recently created Sessions__c record.

 

I figured I needed a way to denote which Sessions__c record was the most recent, so I put a checkbox on the Sessions__c called Most_Recent_Record__c which is checked by default, and wrote a trigger that unchecks that field for all other Sessions__c records related to the same Cycle__c.

 

I then tried to write a trigger that populated the Latest_Session__c field on the Cycle__c object, but it seemed to conflict with the other trigger.

 

Thoughts?? There is a date field on the Sessions__c object, so if that helps and means that I don't need the Most recent checkbox that is fine.

 

Here is the trigger for unchecking "most recent record" on the Sessions__c object:

trigger clearmostrecentflag on Sessions__c (before insert) {
 
//create a list to hold the records to update
List<Sessions__c> oldrecords = new List<Sessions__c>();
 
 
for(Sessions__c myrecord: trigger.new){
String parentname = myrecord.Cycle__c;
String myrecordid = myrecord.Id;
   for (Sessions__c myrecordlist : [select Cycle__c from Sessions__c where Cycle__c =:parentname AND Id != :myrecordid AND Most_Recent_Session2__c = true]){
 
 
myrecordlist.Most_Recent_Session2__c = false;
oldrecords.add(myrecordlist);
  
}
}
if(oldrecords.size()>0) {
update oldrecords;
}
else{
//do nothing
}
 
}

 Here is the trigger I attempted to write, to update the blank Latest_Session__c lookup field on the Cycle__c object (essentially, I want that field populated with whichever child Sessions__c record has Most_Recent_Record__c checked as true).

 

trigger updateLatestSession on Sessions__c (after update) {
    Set<Id> CycIds = new Set<Id>();
         for (Sessions__c sess : Trigger.new)
         if(sess.Most_Recent_Session2__c != false){
             CycIds.add(sess.Cycle__c);
}            
    Map<Id, Cycle__c> cycMap = new Map<Id, Cycle__c>(
    [SELECT Id  FROM Cycle__c WHERE Id IN :CycIds]);  
    
        for (Sessions__c sess : Trigger.new){    

         cycMap.get(sess.Cycle__c).Latest_Session__c = sess.ID;       
         
         //create list of ParentObjects
List<Cycle__c> ParentObjectList = cycMap.Values();

//save the ParentObjects
update ParentObjectList; 

} 
}

 The error message I got when trying to create a new Sessions__c:

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger clearmostrecentflag caused an unexpected exception, contact your administrator: clearmostrecentflag: execution of BeforeInsert caused by: System.DmlException: Update failed. First exception on row 0 with id a0DQ00000044zThMAI; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, updateLatestSession: execution of AfterUpdate caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.updateLatestSession: line 12, column 1: []: Trigger.clearmostrecentflag: line 19, column 1

 

Any help would be much appreciated.

 

Thanks!

Best Answer chosen by Admin (Salesforce Developers) 
Naidu PothiniNaidu Pothini
trigger clearmostrecentflag on Sessions__c (before insert, after Insert) 
{
	if(trigger.isInsert)
	{

		if(trigger.isBefore)    // Updates the Most_Recent_Session__c field to True for newly created records && unchecks the old records Most_Recent_session__c
		{
			List<Sessions__c> oldRecords = new List<Sessions__c>();

			Lsit<String> cycleList = new List<String>();

			for(Sessions__c se : Trigger.new)
			{
				cycleList.add(se.Cycle__c);
			}

			for (Sessions__c rec : [SELECT Id, Most_Recent_Session2__c FROM Sessions__c WHERE Cycle__c IN :cycleList AND Most_Recent_Session2__c = true])
			{
				rec.Most_Recent_Session2__c = false;
				oldRecords.add(rec);
			}

			if(oldRecords.size() > 0)
			{
				update oldRecords;   // Clears Most_Recent_Session2__c on Session Records
			}

			for(Sessions__c se : Trigger.new)
			{
				se.Most_Recent_Session2__c = true;   // Checking the most recently created session to True
			}
		}

		if(trigger.isAfter)  // to update the Cycle__c Object records with Latest_Session__c Field values
		{
			List<String> cycleList = new List<String>();

			List<Cycle__c> cyList = new List<Cycle__c>(); 

			for(Sessions__c se : Trigger.new)
			{
				cycleList.add(se.Cycle__c);
			}

			Map<Id, Cycle__c> cycMap = new Map<Id, Cycle__c>([SELECT Id, Latest_Session__c FROM Cycle__c WHERE Id IN :cycleList]);  

                        


			for (Sessions__c sess : Triger.new)
			{    
				Cycle__C cy = cycMap.get(sess.Cycle__c);

				cy.Latest_Session__c = sess.Id;

				cyList.add(cy);
			} 

			update cyList;
		}
	}
 	
}

 try this.

All Answers

Naidu PothiniNaidu Pothini
trigger clearmostrecentflag on Sessions__c (before insert) 
{
 	List<Sessions__c> oldRecords = new List<Sessions__c>();

	Lsit<String> cycleList = new List<String>();

	for(Sessions__c se : Trigger.new)
	{
		cycleList.add(se.Cycle__c);
	}

	for (Sessions__c rec : [SELECT Id, Most_Recent_Session2__c FROM Sessions__c WHERE Cycle__c IN :cycleList AND Most_Recent_Session2__c = true])
	{
		rec.Most_Recent_Session2__c = false;
		oldRecords.add(rec);
	}

	if(oldRecords.size() > 0)
	{
		update oldRecords;
	}
}

 I see few things you are not doing right in the above class like the query inside a loop and have to change it.

 

 

trigger updateLatestSession on Sessions__c (after update) 
{
	Set<Id> CycIds = new Set<Id>();
	
	List<Cycle> cycleList = new List<Cycle__c>();

	List<Sessions__c> sessRecords = new List<Sessions__c>();

	for(Integer i = 0; i < Trigger.new.size(); i++)
	{
		if(Trigger.old[i].Most_Recent_Session2__c == false && Trigger.new[i].Most_Recent_Session2__c == false) // to make sure the update was not unchecking old most recent session record.
		{
			cycIds.add(Trigger.new[i].Cycle__c);
			sessRecords.add(Trigger.new[i]);
		}
	}

	Map<Id, Cycle__c> cycMap = new Map<Id, Cycle__c>([SELECT Id, Latest_Session__c FROM Cycle__c WHERE Id IN :CycIds]);  

	for (Sessions__c sess : sessRecords)
	{    
		Cycle__C cy = cycMap.get(sess.Cycle__c);

		cy.Latest_Session__c = sess.Id;

		cycleList.add(cy);
	} 

	update cycleList;
}

 

Try these two classes and let me know if it doesnt work.

 

brielea1984brielea1984

Thank you for your help! I wound up not getting an error, but the Latest_Session__c field on Cycle__c did not update with the most recent Session created.

 

I'm wondering if it has to do with this section:

 

	Map<Id, Cycle__c> cycMap = new Map<Id, Cycle__c>([SELECT Id, Latest_Session__c FROM Cycle__c WHERE Id IN :CycIds]);  

 Would I be trying to map the Cycle ID to the Cycle__c field on the Session__c object? Using this language is always trial and error for me. What do you think?

 

Thanks again! I really appreciate it!

 

Naidu PothiniNaidu Pothini
trigger clearmostrecentflag on Sessions__c (before insert, after Insert) 
{
	if(trigger.isInsert)
	{
		Lsit<String> cycleList = new List<String>();

		for(Sessions__c se : Trigger.new)
		{
			cycleList.add(se.Cycle__c);
		}

		if(trigger.isBefore)    // Updates the Most_Recent_Session__c field to True for newly created records && unchecks the old records Most_Recent_session__c
		{
			List<Sessions__c> oldRecords = new List<Sessions__c>();

			Lsit<String> cycleList = new List<String>();

			for(Sessions__c se : Trigger.new)
			{
				cycleList.add(se.Cycle__c);
			}

			for (Sessions__c rec : [SELECT Id, Most_Recent_Session2__c FROM Sessions__c WHERE Cycle__c IN :cycleList AND Most_Recent_Session2__c = true])
			{
				rec.Most_Recent_Session2__c = false;
				oldRecords.add(rec);
			}

			if(oldRecords.size() > 0)
			{
				update oldRecords;   // Clears Most_Recent_Session2__c on Session Records
			}

			for(Sessions__c se : Trigger.new)
			{
				se.Most_Recent_Session2__c = true;   // Checking the most recently created session to True
			}
		}

		if(trigger.isAfter)  // to update the Cycle__c Object records with Latest_Session__c Field values
		{
			Map<Id, Cycle__c> cycMap = new Map<Id, Cycle__c>([SELECT Id, Latest_Session__c FROM Cycle__c WHERE Id IN :cycleList]);  

List<Cycle__c> cyList = new List<Cycle__c>();
for (Sessions__c sess : Triger.new) { Cycle__C cy = cycMap.get(sess.Cycle__c); cy.Latest_Session__c = sess.Id; cyList.add(cy); } update cyList; } } }

 Probably you might need to have after insert trigger to update the cycle__c record with the latest_Session__c Id.

brielea1984brielea1984

I got this error:

 

Error: Compile Error: Duplicate variable: cycleList at line 16 column 26

 

which is the 

List<String> cycleList = new List<String>();
 
in the isBefore that updates the most recent session field
 
 
Naidu PothiniNaidu Pothini
trigger clearmostrecentflag on Sessions__c (before insert, after Insert) 
{
	if(trigger.isInsert)
	{

		if(trigger.isBefore)    // Updates the Most_Recent_Session__c field to True for newly created records && unchecks the old records Most_Recent_session__c
		{
			List<Sessions__c> oldRecords = new List<Sessions__c>();

			Lsit<String> cycleList = new List<String>();

			for(Sessions__c se : Trigger.new)
			{
				cycleList.add(se.Cycle__c);
			}

			for (Sessions__c rec : [SELECT Id, Most_Recent_Session2__c FROM Sessions__c WHERE Cycle__c IN :cycleList AND Most_Recent_Session2__c = true])
			{
				rec.Most_Recent_Session2__c = false;
				oldRecords.add(rec);
			}

			if(oldRecords.size() > 0)
			{
				update oldRecords;   // Clears Most_Recent_Session2__c on Session Records
			}

			for(Sessions__c se : Trigger.new)
			{
				se.Most_Recent_Session2__c = true;   // Checking the most recently created session to True
			}
		}

		if(trigger.isAfter)  // to update the Cycle__c Object records with Latest_Session__c Field values
		{
			List<String> cycleList = new List<String>();

			List<Cycle__c> cyList = new List<Cycle__c>(); 

			for(Sessions__c se : Trigger.new)
			{
				cycleList.add(se.Cycle__c);
			}

			Map<Id, Cycle__c> cycMap = new Map<Id, Cycle__c>([SELECT Id, Latest_Session__c FROM Cycle__c WHERE Id IN :cycleList]);  

                        


			for (Sessions__c sess : Triger.new)
			{    
				Cycle__C cy = cycMap.get(sess.Cycle__c);

				cy.Latest_Session__c = sess.Id;

				cyList.add(cy);
			} 

			update cyList;
		}
	}
 	
}

 try this.

This was selected as the best answer
brielea1984brielea1984

THANK YOU!!!!! It worked! I appreciate you helping me work through this!