A FieldPath is a sequence of Field instances that represent the path from the root of the schema down to a particular Field that is of interest.
If a Field instance is a “what”, then a FieldPath is a “where”. You can pretty easily think of a FieldPath as an array of strings where each item is the name of a field.
FieldPath is an appropriate tool when thinking about and interacting with schema information, but for actual record interactions we’ll use Property Path.
Building an Instance
global static FieldPath buildPath(List<Field> fields); global static FieldPath buildPath(Field field); global static FieldPath buildPath(List<String> fieldNames); global static FieldPath buildPath(String fieldName);
// get the full chain of Fields global List<Field> getSequence() // get the Field at the end of the chain (the leaf) global Field getLast() // get the the field name of each Field in the sequence global List<String> getSimplePath()
Suppose you are working with the LastName field on the Contact object in Salesforce.
If we were just working within the Contact object, getSequence() would be a List with one Field instance:
// [LastName] List<Field> fields = path.getSequence(); fields.size(); // 1 fields.name; // LastName fields.type; // STRING fields.isRequired; // true fields.isList; // false
However, what if we were actually building a Link against the Account object, and wanted to refer to related Contact records? There is a Master-Detail field Contact.AccountId, whose inverse from the Account side is called Contacts (with an S).
So in this scenario, from the perspective of the Account object, we’d be interested in looking at Contacts.LastName.
// [Contacts,LastName] List<Field> fields = path.getSequence(); fields.size(); // 2 fields.name; // Contacts fields.type; // CHILDREN fields.isRequired; // false fields.isList; // true fields.name; // LastName fields.type; // STRING fields.isRequired; // true fields.isList; // false
So the same Field (Contact.LastName) might be referenced with different paths. You might even have the same Field referenced by different paths in the same schema.
FieldPath helps us encapsulate this and makes it easier to work with arbitrarily-nested Fields.
As you can see from methods like buildPath(List<String> fieldNames), sometimes you will have a FieldPath whose Field instances have sparsely-populated properties (in this example, only Field.name would have a value); name and isList are the only two properties you can safely assume will always be set.