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
ag415ag415 

How to check values of fields of related records in an 'if' statement in Apex

Hello,

I originally posted this question in the Salesforce Answers Community, but I was told that it would be best to post this here instead.

I am working an Apex trigger that performs an action based on the condition that two fields equal a certain a value (or in this case, DON'T equal a certain value). One of the fields is a custom boolean field on the record that the trigger is firing for - which works fine - but the other is a field on a related record that is linked to that record via a lookup field.

The object the trigger is executing for is the Contacts object. I have an 'if' statement in the trigger that checks the value of the custom "Private__c" boolean field on the contact record as well as another custom boolean field (also called "Private__c") on the account record linked to the contact record via the Account lookup field.

Basically, I want my trigger to check if "Private__c" on the contact record and "Private__c" on the related account record are both false, and then execute some code if they are. Else, execute some different code.

So far, my code looks a little something like this:

for (Contact c : Trigger.new) {
    if(! c.Private__c && ! c.Account.Private__c) {
        "do stuff"
    } else {
        "do something else"
    }
}
But this doesn't seem to work, even though the developer console doesn't seem to complain about any unknown fields or other errors as I would expect it to if "c.Account.Private__c" wasn't a valid field. Am I missing something here? Is it not possible to reference fields belonging to the related record this way? And if so, what is the correct way to reference them so I can check their values in an 'if' statement?

I'd appreciate any help I can get on this one.

Thanks!
Best Answer chosen by ag415
James LoghryJames Loghry
Other than the Ids of the relationships themselves, Related fields are not returned in the trigger context (Trigger.new or Trigger.newMap in other words).

Instead, you will need to requery for Account.Private__c.

The following example will work if your trigger is *not* before insert:

for(Contact c : [Select Private__c,Account.Private__c From Contact Where Id in :Trigger.newMap.keySet()){
    if(!c.Private__c && !c.Account.Private__c){
        //
    }else{
       //
    }
}

Now, if you are doing this in a before insert trigger, you'll need a little bit more logic, because Trigger.newMap does not exist in this context, nor do the Contact record Ids exist yet.  For before insert, your logic may look like:

Set<Id> accountIds = new Set<Id>();
for(Contact c : Trigger.new){
    accountIds.add(c.AccountId);
}

Map<Id,Account> accountMap = new Map<Id,Account>([Select Private__c From Account WHere id in :accountIds]);

for(Contact c : Trigger.new){
    if(!c.Private__c && !accountMap.get(c.AccountId).Private__c){
        //
    }else{
       //
    }
}


All Answers

Deepak Kumar ShyoranDeepak Kumar Shyoran
I have created two new checkbox type field Private__c on Contact and Account and Below code is working for me and give expected result.

for(Contact con :trigger.new) {
		
		
		  if(! con.Private__c && ! con.Account.Private__c) {
		  	System.debug('--if--'); 
		  }
		  else
		  	System.debug('--else--'); 
		
	}

Please check make sure you are using valid field type of for Priveate__c custom field in your case.
James LoghryJames Loghry
Other than the Ids of the relationships themselves, Related fields are not returned in the trigger context (Trigger.new or Trigger.newMap in other words).

Instead, you will need to requery for Account.Private__c.

The following example will work if your trigger is *not* before insert:

for(Contact c : [Select Private__c,Account.Private__c From Contact Where Id in :Trigger.newMap.keySet()){
    if(!c.Private__c && !c.Account.Private__c){
        //
    }else{
       //
    }
}

Now, if you are doing this in a before insert trigger, you'll need a little bit more logic, because Trigger.newMap does not exist in this context, nor do the Contact record Ids exist yet.  For before insert, your logic may look like:

Set<Id> accountIds = new Set<Id>();
for(Contact c : Trigger.new){
    accountIds.add(c.AccountId);
}

Map<Id,Account> accountMap = new Map<Id,Account>([Select Private__c From Account WHere id in :accountIds]);

for(Contact c : Trigger.new){
    if(!c.Private__c && !accountMap.get(c.AccountId).Private__c){
        //
    }else{
       //
    }
}


This was selected as the best answer
ag415ag415
Hi James,

Thanks for the info. I tried your solution (and also Deepak's), but unfortunately those didn't work either. Your solution did give me an idea, however. I tried doing this instead:

for (Contact c : Trigger.new) {
    Account ca = [
        SELECT Id, Private__c
        FROM Account
        WHERE Id=:c.AccountId
    ];
    if(! c.Private__c && ! ca.Private__c) {
        "do stuff"
    } else {
        "do something else"
    }
}
This works! I guess I just needed to query the account record separately before the 'if' statement. Thanks for the help
James LoghryJames Loghry
Why would my solution not work?  By the way the solution you picked is not a good idea.  You're querying in a for loop, so your trigger will handle at most 100 records before you run into a too many queries exception thrown.
ag415ag415
Not sure... but I tried it, and it just wouldn't work. I tried the first code example you gave me (didn't trigger any syntax errors other than the missing closing bracket, which I fixed), but it just wouldn't work even though my trigger isn't firing "before insert."
ag415ag415
Ok just an update: James, it turns out that your code does work. The reason it wasn't working for me was because I was performing some operations involving certain contact fields that I hadn't selected in the for loop's initial SOQL query. Once I added the fields to the SOQL query, your code worked perfectly. Sorry for the confusion! I've selected yours as the best answer as this is far more efficient than my workaround.