Skip to content

configureQueryFactory for lookup based on fieldset #222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
cropredyHelix opened this issue Apr 18, 2019 · 2 comments
Open

configureQueryFactory for lookup based on fieldset #222

cropredyHelix opened this issue Apr 18, 2019 · 2 comments

Comments

@cropredyHelix
Copy link

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?

@ClayChipps
Copy link
Contributor

@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?

@cropredyHelix
Copy link
Author

cropredyHelix commented May 15, 2020

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants