How to find an Object Child Relationship Name

Author: Bruce Tollefson Published: May 10, 2022; Modified: May 10, 2022
bullhorn

Salesforce SOQL doesn’t have traditional joins, instead, there are 2 different types of relationship queries: Parent-to-Child and Child-to-Parent. Child-to-Parent SOQL queries is Salesforce’s way to join a list of child-related records with a parent record. In order to obtain the list of child records and their data the SOQL query must look something similar to:

SELECT Name, ( SELECT LastName FROM Contacts ) FROM Account

In the above example, we get a list of all contacts that are associated with each Account record. As you can see the Contact object is referenced using the object’s child relationship name of Contacts (plural). In a custom object, the relationship name is created during the lookup field creation. As an example create a custom object such as; Opp Child, with a developer name of Opp_Child__c. Next, create a custom lookup or master-detail field Opportunity__c with a relationship name of Opp_Children:

Opp_Child__c Image

Resulting in a Child-to-Parent using the child relationship name with __r appended and not the object name such as:

Select Id, (Select Id from Opp_Children__r) from Opportunity

Going to the lookup field works for custom fields and some standard fields where you can view the field in object manager. However what about standard fields that aren’t in object manager. What if you wanted to query the Opportunity and OpportunityFeed. The standard naming convention of other objects would make me think it would be OpportunityFeeds however that is not correct and provides an error.

How to find a Relationship Name for any Object

So how do we find the correct child relationship name? We can use the getDescribe() method with the getChildRelationship() method to get the object child relationship name with the ChildRelationship class. In the following custom class we are dynamically creating an sObject based on the name of the of that object and the name of the child object we are trying to find the relationship name for:

public static String getChildRelationshipName(String parentsObj, String childsObj) { //Create sobject Instance sObject dynamicObj = (SObject)Type.forName(parentsObj).newInstance(); //get the type token SObjectType sObjType = dynamicObj.getSObjectType(); //get describe DescribeSobjectResult sObjDescribe = sObjType.getDescribe(); //loop through children for(Schema.ChildRelationship rels :sObjDescribe.getChildRelationships()){ //find the child if(String.ValueOf(rels.getChildSObject()) == childsObj){ return rels.getRelationshipName(); } } return null; }

Next just call that method (I placed it in a ChildRelationshipService class):

system.debug(ChildRelationshipService.getChildRelationshipName('Opportunity', 'OpportunityFeed'));

Can we can see the OpportunityFeed relationship name is actually Feeds. Next we can run the following:

Select Id, (Select Id, Title, Body from Feeds) from Opportunity

If you would like to return a map of the ChildRelationships for the object you can use the following:

public static Map<String, ChildRelationship> getChildRelationshipMap(String parentsObj){ Map<String, ChildRelationship> sObjChildRelationshipName = new Map<String, ChildRelationship>(); //Create sobject Instance sObject dynamicObj = (SObject)Type.forName(parentsObj).newInstance(); //get the type token SObjectType sObjType = dynamicObj.getSObjectType(); //get describe DescribeSobjectResult sObjDescribe = sObjType.getDescribe(); //loop through children for(Schema.ChildRelationship rels :sObjDescribe.getChildRelationships()){ //put the child in map sObjChildRelationshipName.put(String.ValueOf(rels.getChildSObject()), rels); } return sObjChildRelationshipName; }

If you would like use the map instead you can run the following:

system.debug(ChildRelationshipService.getChildRelationshipMap('Opportunity').get('OpportunityFeed').getRelationshipName());

Here is the Github repo.

Leave a Reply

Your email address will not be published. Required fields are marked *