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
imaliveagainimaliveagain 

Trigger not updating a lookup field on a parent record

Hi my skills are pretty basic however I think my task is pretty basic with this trigger.  I've looked on the boards and found people answering this question but I am missing something and was hoping someone could let me know what I'm missing.  Because you can't update a lookup field on a parent record master-detail through a workflow rule I am writing a trigger to do it. 

Scenario:

I have three objects  IC_Asset__c  is the parent of a master-detail relationship with Checkin_Checkout_History__c .  On IC_Asset object there is a lookup field called In_possession_of__c to a Staff__c object.  On Checkin_Checkout_History__c there is a lookup field called Asset_History__c to the same Staff__c object.

 

I want to write the contents of Asset_History__c field to In_possesion_of__c field on IC_Asset__c after an edit on Checkin_Checkout_History__c.

---------------------------------------------------------------------------------------------------------------------------

trigger SetInPossessionOf on Checkin_Checkout_History__c (before update) {

//create a set of all unique IC_Asset ids

    Set<Id> assetIds = new Set<Id>();
         for (Checkin_Checkout_History__c chk : Trigger.new)
    // Add ids of lookup on Checkin_Checkout_History__c to assetIds
            assetIds.add(chk.Asset_Lookup__c);
        
// create a map so that IC_Assets are locatable by Id
    Map<Id, IC_Asset__c> icaMap = new Map<Id, IC_Asset__c>(
    [SELECT Id,In_possession_of__c,text_field_asset__c FROM IC_Asset__c WHERE Id IN :assetIds]);
    
    for (Checkin_Checkout_History__c chk : Trigger.new){
        // get the IC_Asset__c from the map by its id
         icaMap.get(chk.Asset_Lookup__c).In_possession_of__c = chk.Staff__c;

-------------------------------------------------------------------------------------------------------------------------------------

Nothing happens. 

 

I can copy field to field on the record

chk.text_field__c = chk.text_field_chkout__c;

I can even copy from the parent lookup to a text field

chk.text_field_chkout__c= icaMap.get(chk.Asset_Lookup__c).In_possession_of__c;

But when I try to copy up to the parent I get nothing whether copying to a lookup or text field

icaMap.get(chk.Asset_Lookup__c).text_field_asset__c = chk.text_field_chkout__c;

 

Please help, thanks

 

Best Answer chosen by Admin (Salesforce Developers) 
ahab1372ahab1372

you update the IC_Asset__c records only within the trigger context, but you never save these changed records back into the database.

The records are the values in the icaMap, so after the last for-loop, add an

update icaMap.values();

 That should do it

 

Arnt

 

All Answers

ahab1372ahab1372

you update the IC_Asset__c records only within the trigger context, but you never save these changed records back into the database.

The records are the values in the icaMap, so after the last for-loop, add an

update icaMap.values();

 That should do it

 

Arnt

 

This was selected as the best answer
BrianWKBrianWK

I think I see what you're trying to do.

 

You have a child record Checkin_Checkout_History__c. When this record is edited, you want it to update the Parent Record Object IC_Asset__c.

 

This is why it's not working.

 

Your Before Trigger is updating Checkin_Checkout_History__c objects and not the Parent Object. So when your trigger is fired, the Parent Object's field gets written -- but not actually updated. Basically, what you're doing is like going to edit the parent record - but not actually saving it.


I would do this:

trigger SetInPossessionOf on Checkin_Checkout_History__c (before update) {

//create a set of all unique IC_Asset ids

    Set<Id> assetIds = new Set<Id>();
         for (Checkin_Checkout_History__c chk : Trigger.new)
    // Add ids of lookup on Checkin_Checkout_History__c to assetIds
            assetIds.add(chk.Asset_Lookup__c);
         
// create a map so that IC_Assets are locatable by Id
      Map<Id, IC_Asset__c> icaMap = new Map<Id, IC_Asset__c>([SELECT Id,In_possession_of__c,text_field_asset__c FROM IC_Asset__c WHERE Id IN :assetIds]);

    for (Checkin_Checkout_History__c chk : Trigger.new){
        // get the IC_Asset__c from the map by its id
         icaMap.get(chk.Asset_Lookup__c).In_possession_of__c = chk.Staff__c;}

//create list of ParentObjects
List<IC_Asset__c> ParentObjectList = icaMap.Values();

//save the ParentObjects
update ParentObjectList;

 

basically you update the parent record, shove those parents into a list, then "save" the parents by doing an update.

 

My only concern here is if you have multiple checkin_checkout_history__c objects related to the same parent and have difference Staff__c values. Which one would you expect to get written to the parent?

 

ahab1372ahab1372

Brian and I basically have the same idea. I think it is not necessary to copy the records from the Map to a list before updating, but the result will be the same.

I agree with Brian's concern, the last checkin_checkout_history__c record will overwrite any changes from other records to the same parent record. But maybe that is how you want it to work, it really depends on your business case.

imaliveagainimaliveagain

Yes!!  That worked thank you.

imaliveagainimaliveagain

It's a checkout type system and I want to have it overwrite the lookup with no record on the staff object except when the asset is currently assigned to them.  Conceptually it's like moving an item from one bin to another bin.  The record of where it's been will be on the asset instead of the staff object.

 

Thanks for the quick response.

BrianWKBrianWK

Ahab,

 

I like your solution of updating directly from the map.values()...

 

I've gotten in the habit of shoving everything in lists just for degbug purposes. Plus, I tend to declare all my variables at the top of my trigger/class based on my design. This way if I dev and I forget to use a variable I know I either screwed up in my dev or in my design:)

 

Not elegant, but it works:)