0

I'm trying to save a new record dynamically, but I'm having a problem with a lookup field. For instance, I'm able to get the parent object with the id.

Id relatedID = '<someId>';
SObjectType parentObj = relatedID.getSobjectType();

But let's say as ab example, parentObj = Supervisor__c and the object I need to insert is Employee__c. The field name on for the lookup on Employee__c to Supervisor__c is called Manager__c (which I want to get and set dynamically). How can I get and set that field name with an insert? I know getReferencedTo() will return the object, but not sure how to go from the object to the field set it with dynamic dml.

This works, but it's rather ugly and I'm sure I'm missing something and it can be simplified.

Id relatedId = '<some id>';
SObjectType supervisorType = relatedID.getSobjectType();
SObjectType employeeType = Schema.getGlobalDescribe().get('Employee__c');
SObject employee = employeeType.newSObject();

Schema.DescribeSObjectResult objSchema = Employee__c.sObjectType.getDescribe();
Map<String, Schema.SObjectField> fieldMap = objSchema.fields.getMap();
for(Schema.SObjectField sfield : fieldMap.Values()) {
    if (sfield.getDescribe().getReferenceTo().size() > 0) {
          if (sfield.getDescribe().getReferenceTo()[0] == supervisorType) {
              employee.put(sfield.getDescribe().getName(), relatedId);
              System.debug(story);
              break;
          }
    }
}
  • if I understand you correctly, you have a field token (Manager__c) on the Employee__c object. The value of the that field has to be the ID value of the parent Supervisor__c object. So, the apex is simply employeeObj.put(managerFldToken,idValOfSupervisor) – cropredy Jun 21 '16 at 4:01
  • @cropredy Yes, but if I understand correctly, that still leaves me with my original problem. I edited my original post with what works, but there must be a way to simplify it. – Andrew L. Jun 21 '16 at 16:10
  • 1
    employee.put(sfield.getDescribe().getName(), relatedId); can be employee.put(sfield, relatedId); but I gather that what you're trying to simplify is avoidance of the loop. The issue is that a given child object can have multiple lookup fields to the same parent object and hence knowing the parent object Id doesn't give you enough info to identify the foreign key field in the child (Employee). You have to know the relationship name to identify the appropriate child lookup field – cropredy Jun 21 '16 at 16:37
  • @cropredy Thanks. I may be better off just creating a custom map with the object as the key to return the field I need. What I have is an example. Basically, the real page has the one object that has 5 lookup fields, but only 1 will be set and saved depending on a selection. – Andrew L. Jun 21 '16 at 17:31
1

As I understand the question, for a given child sObject and a given parent (lookup) object's ID, how do you locate the child object's lookup field name or token?

In your example,

Employee__c has several lookup fields to several parents. If you have some parentId, you can easily get the SObjectType of the parent with parentId.getSobjectType() but what is the corresponding fieldname/token in Employee__c?

There's no way to derive this dynamically from the describe information reliably because a given child SObject can have multiple lookup fields to the same parent SObject.

A classic example of this in Opportunity wherein I often see folks adding lookup fields to key Contacts such as BillToContact__c and ShipToContact__c (rather than using OpportunityContactRole which has some challenges for other reasons)

If you had an Opportunity and an ID of some Contact, which of the two Opportunity lookup fields to Contact do you try and set with the someContactId?

You can't, because it is the relationship name that tells you which lookup field to use and the relationship name can't be derived from someContactId

As you stated in your comment, in a limited application wherein you guaranteed that there were never multiple lookup fields to the same parent, you could build a map of:

map<SobjectType,SobjectField> parentTypeToChildFldTokenMap

and then you could look up the field token of the child object with:

SobjectField fldToken = parentTypeToChildFldTokenMap.get(someParentId.getSObjectType());

Otherwise, the application needs to know which relationship the someParentId participates in to ascertain the child fieldToken. Then, you would go to the parent's Describe result and loop through the ChildRelationships looking for a match on relationshipname. The ChildRelationship object contains the fieldtoken of the child lookup field.

  • Yes, this is a limited application so I went with a custom map an it working as needed. I marked this as the answer and thanks for the explanation. – Andrew L. Jun 28 '16 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.