I am attempting to write generic code which will use a fieldset, allowing for dynamic creation of a query. This bit is documented well enough in dynamic DML examples from SFDC. In addition to the dynamic query, I also need to describe the fields which are included in the fieldset.
My dilemma comes from not understanding the method in which I should approach getting field describe information about fields which are included within the fieldset on related (lookup) objects.
For the purpose of this example I will describe it as Answer__c
and Question__c
, with a lookup field defined on Answer__c
to Question__c
.
I have a fieldset defined on Answer__c
which includes both fields from Answer__c
as well as Question__c
. When building the dynamic query from the fieldset, we use the FieldSetMember.getFieldPath()
to build the query string which results in the usual child-parent path span in the form of Question__r.Id
, Question__r.Name
, etc.
What I am having trouble understanding is how to do a describe of the fields which are in the fieldset on the related objects without knowing the related objects and fields in advance. The fieldset should be able to be modified to include fields from any related object and the code should continue to work, describing the fields through the relationship.
I hesitate to perform something like a string split on the results of the .getFieldPath()
result to determine which objects and fields to describe as I suspect that there is a better method.
List<Schema.FieldSetMember> fieldsetMembers =
Schema.SObjectType.Answer__c.fieldSets.getMap().get('field_set_name').getFields();
// don't want to do _this_ hardcoding of the type
// otherwise we would need all fields from all objects in the org
Map<String, Schema.SObjectField> answerFieldMap = Schema.sObjectType.Answer__c.fields.getMap();
for (FieldSetMember member : fieldsetMembers) {
// this works when the fieldpath does not include a field that spans a relationship
// because the answerFieldMap contains only the fields on Answer__c
// and none of the fields on Question__c
Schema.Sobjectfield f = answerFieldMap.get(member.getFieldPath());
Schema.DescribeFieldResult fDescribe = f.getDescribe();
fieldsetDescribesMap.put(fDescribe.getName(), fDescribe);
}
The code above will throw an exception such as Invalid field Question__r.Name for Answer__c
when member.getFieldPath()
returns Question__r.Name
for the path to the field.
Is there a bulletproof method to describe all of the fields on all of the objects referenced in a fieldset?
Related Docs:
Best Answer
You'll need to build out the recursive function. I'd built one for accessing query data recursively without having to worry about lookup relationships. You can probably modify it to work for your requirements, just make sure you're caching any fields calls so you don't blow that limit.