fflib-apex-common icon indicating copy to clipboard operation
fflib-apex-common copied to clipboard

configureQueryFactory for lookup based on fieldset

Open cropredyHelix opened this issue 5 years ago • 2 comments

In fflib_SObjectSelector we have a useful method to add lookup fields from a selector instance to an existing queryFactory

public void configureQueryFactoryFields(fflib_QueryFactory queryFactory, String relationshipFieldPath)
{
  // Add fields from selector prefixing the relationship path		
  for(SObjectField field : getSObjectFieldList())		
   queryFactory.selectField(relationshipFieldPath + '.' + field.getDescribe().getName());
  // Automatically select the CurrencyIsoCode for MC orgs (unless the object is a known exception to the rule)
  if(Userinfo.isMultiCurrencyOrganization() && CURRENCY_ISO_CODE_ENABLED)
     queryFactory.selectField(relationshipFieldPath+'.CurrencyIsoCode');		
}

Use case from Force.com Enterprise Architecture second edition p 228 is

fflib_QueryFactory contestantFactory = newQueryFactory();
new DriversSelector()
  .configureQueryFactoryFields(contestantFactory,'Driver__r');
return Database.query(contestantFactory.setCondition(...).toSOQL());

Seems like it would be useful (at least to me) to be able to configure the parent lookup fields via a fieldset as in:

fflib_QueryFactory contestantFactory = newQueryFactory();
new DriversSelector()
  .configureQueryFactoryFields(contestantFactory,
                    'Driver__r',SObjectType.Driver.fieldsets.MyFieldSet);
return Database.query(contestantFactory.setCondition(...).toSOQL());

where the code for this in fflib_SObjectSelector would be something like this:

/**
* adds a specific fieldset to a given relationship (lookup) as a prefix
 */
public void configureQueryFactoryFields(fflib_QueryFactory queryFactory, String relationshipFieldPath, Schema.FieldSet fieldSet) {
   //	Add fields from fieldSet to queryFactory prepended by relationshipFieldPath
   if (fieldSet.getSObjectType() != getSObjectType()) {
    throw new fflib_QueryFactory.InvalidFieldSetException('Field set "' + fieldSet.getName() +
		'" is not for SObjectType ' + getSObjectType());
  }
  for (Schema.FieldSetMember field: fieldSet.getFields()) {
    queryFactory.selectField(relationshipFieldPath + '.' + field.getFieldPath());
  }
  if(Userinfo.isMultiCurrencyOrganization() && CURRENCY_ISO_CODE_ENABLED) {
    queryFactory.selectField(relationshipFieldPath+'.CurrencyIsoCode');
  }
}

Or is there some existing way to do this that I have overlooked (configuring a queryfactory's lookup fields via a fieldset of the parent Sobject?

cropredyHelix avatar Apr 18 '19 18:04 cropredyHelix

@cropredyHelix I believe I am working on some functionality that would allow this, but with a slight variation from what you have suggested. Instead of passing the fieldset that you want included, I think it would make more sense to automatically include any fieldsets that are configured at the Selector layer, when overriding the getSObjectFieldSetList() method.

Do you think this would solve the ask, or do you still see benefit in passing a specific fieldset to add from?

ClayChipps avatar May 15 '20 03:05 ClayChipps

@ctchipps so, the reason why I suggested a specific fieldset was for a use case where each SObject had two or more fieldsets defined, one of which was called ViewStateOptimized. So, if a selector method on OpportunityLineItem was invoked in a use case where viewstate was trying to be minimized, the queryfactories for Opportunity, PricebookEntry, PricebookEntry.Product2, and Opportunity.Accountcould all draw from their respectiveViewDtateOptimized` (by passing in as an arg) fieldset. Other use cases might choose different fieldsets from their lookup relationship's selector.

the override of getSobjectFieldSetList() would possibly include more fieldsets than desired. I suppose one could subclass selectors just to specify different default fieldsets

I'm open to other ideas but the intent is to tell the queryFactory which fieldset to use when configuring a lookup relationship from the relationship's selector object.

cropredyHelix avatar May 15 '20 04:05 cropredyHelix