function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Oliver_DunfordOliver_Dunford 

Insert Child Record on Parent Record Insert

Hi There, 

 

I'm new to APEX and I'm struggling to get some code working.  I wanted to make it nice and neat and do things right rather than swamping it all with for loops etc.  A single Slot__c record will be created and them I'm looking to insert a list of records into a child object (master detail).

 

My code below goes off and returns a list of Treatment__c records and inserts into a map.  All is well so far.  I am now struggling with the following:

 

1. The trigger fires after the creation of a Slot__c record.  For each inserted parent I would like to also insert the Slot__c.Id value into a variable within the Map so I can relate the child record to it's parent upon insertion.

 

2. My SOQL query WHERE clause has duration hard coded to <= '100'.  I would like to include the Slot__c.Duration field from the Parent Record here instead.

 

3. I then want to take my map and insert all these records into an object Available_Treatments__c.  I'm struggling to do this as well.

 

I'm pretty new to all this, so help would be appreciated.  I may well be over complicating it.

 

trigger InsertAvailableTreatments on Slots__c (after insert) {

 

Map<id,List<Treatment__c>> mapTreatmentObj = new Map<id,List<Treatment__c>>();
for(Treatment__c tr : [SELECT Id, Name, Account__c, Duration__c FROM Treatment__c WHERE Duration__c <= '100']) {
List<Treatment__c> treatmentsForKey = mapTreatmentObj.get(tr.Id);
if (treatmentsForKey == null) {
treatmentsForKey = new List<Treatment__c>();
mapTreatmentObj.put(tr.Id, treatmentsForKey);
}
treatmentsForKey.add(new Treatment__c( Id = tr.Id, Name = tr.Name, Duration__c = tr.Duration__c, Account__c = tr.Account__c ));
System.Debug('Name' + tr.Name);
}

}

 

Best Answer chosen by Admin (Salesforce Developers) 
kreshokresho

What your code does is:

  • select all Treatment__c record for which duration__c is <100. The inserted Slot__c is not taken into account in any way.
  • create a map of treatmet__c.id => treatment__c record which is an exact copy of selected Treatment__c record previously selected
  • because treatment__c is inserted into the map by its own Id, the map values wil always be lists of 1 element

I doubt this is in any way useful to you.

 

You code should probably look something like this:

trigger InsertAvailableTreatments on Slots__c (after insert) {
	Integer maxDuration = 0;
	for (Slot__c slot : Trigger.new) {
		if (slot.duration__c > maxDuration) {
			maxDuration = slot.duration__c;
		}
	}
	
	Treatment__c treatments = [
		select Id, Name, Account__c, Duration__c FROM Treatment__c WHERE Duration__c <= :maxDuration
	];
	
	List<Available_Tratments__c> availableTreatments = new List<Available_Tratments__c>();
	for (Slot__c slot : Trigger.new) {
		for (Treatment__c treatment : treatments) {
			if (treatment.duration__c <= slot.duration__c) {
				availableTreatments.add(new Available_Tratments__c(slot__c = slot.id, treatment__c = treatment.id);
			}
		}
	}
	
	insert availableTreatments;
}

 I'm assuming here that Available_Tratments__c is a junction table (for many-to-many relationship, joing slot to treatment).

 

Hope this helps,

 

Regards,
Kresimir
Apex Editor LS - free alternative to Force.com apex editor.

 

All Answers

kreshokresho

What your code does is:

  • select all Treatment__c record for which duration__c is <100. The inserted Slot__c is not taken into account in any way.
  • create a map of treatmet__c.id => treatment__c record which is an exact copy of selected Treatment__c record previously selected
  • because treatment__c is inserted into the map by its own Id, the map values wil always be lists of 1 element

I doubt this is in any way useful to you.

 

You code should probably look something like this:

trigger InsertAvailableTreatments on Slots__c (after insert) {
	Integer maxDuration = 0;
	for (Slot__c slot : Trigger.new) {
		if (slot.duration__c > maxDuration) {
			maxDuration = slot.duration__c;
		}
	}
	
	Treatment__c treatments = [
		select Id, Name, Account__c, Duration__c FROM Treatment__c WHERE Duration__c <= :maxDuration
	];
	
	List<Available_Tratments__c> availableTreatments = new List<Available_Tratments__c>();
	for (Slot__c slot : Trigger.new) {
		for (Treatment__c treatment : treatments) {
			if (treatment.duration__c <= slot.duration__c) {
				availableTreatments.add(new Available_Tratments__c(slot__c = slot.id, treatment__c = treatment.id);
			}
		}
	}
	
	insert availableTreatments;
}

 I'm assuming here that Available_Tratments__c is a junction table (for many-to-many relationship, joing slot to treatment).

 

Hope this helps,

 

Regards,
Kresimir
Apex Editor LS - free alternative to Force.com apex editor.

 

This was selected as the best answer
Oliver_DunfordOliver_Dunford

Thanks Kresimir,  really appreciate you taking the time to reply.  I had a play last night and your code worked nicely.  One more question for you if you don't mind.

 

I added another variable to store the AccountId of the inserted Slot__c record as well.  Is this the most effecient method of accessing field values from an inserted record or is there another way?

 

Final Code Snippet:

 

trigger InsertAvailableTreatments on Slots__c (after insert) {
    Decimal maxDuration = 0;
    String AccountId = '';
    	for (Slots__c slot : Trigger.new) {
            if (slot.duration_mins__c > maxDuration) {
                maxDuration = slot.Duration_mins__c;
                AccountId = slot.Account__c;
            }
        }
    	System.Debug('Max Duration ' + maxDuration);
    	System.Debug('Account Id ' + AccountId);
        
        List<Treatment__c> treatments = [select Id, Name, Account__c, Duration_Int__c FROM Treatment__c WHERE Account__c =: AccountId AND Duration_Int__c <=: maxDuration 
        ];
        System.Debug('List of Treatments ' + treatments);
    
        List<Available_Treatments__c> availableTreatments = new List<Available_Treatments__c>();
       	for (Slots__c slot : Trigger.new) {
            for (Treatment__c treatment : treatments) {
               if (treatment.Duration_Int__c <= slot.Duration_mins__c) {
                   AvailableTreatments.add(new Available_Treatments__c(Slot__c = slot.id, treatment__c = treatment.id));
            
                }
            }
        }        
        insert availableTreatments;
}

 

 

kreshokresho

You don't need to do anything special to get the id of the inserted record.

 

See this example:

Account a = new Account(firstname = 'abc', lastname = 'def');
insert a;
System.debug(a.id);

As you will see, the id is populated by the insert statement and you can use it directly from there.

 

Hope this helps,

 

Regards,
Kresimir
Apex Editor LS - free alternative to Force.com apex editor.