Advanced 30 min read

Build Configurable Business Rules (Custom Metadata)

By the end of this lesson, you'll be able to:

  • Query Case_Routing_Rule__mdt and build an in-memory lookup structure
  • Match a Case's Priority and Type against the configured rules
  • Explain why the metadata is queried once per transaction, not once per Case

Prerequisites: "Enforce Field-Level Security"

Querying the rules once

List<Case_Routing_Rule__mdt> rules = [
    SELECT Priority__c, Case_Type__c, Queue_Name__c
    FROM Case_Routing_Rule__mdt
];
  1. List<Case_Routing_Rule__mdt> rules = [ — custom metadata is queried with regular SOQL (Module 29).
  2. SELECT Priority__c, Case_Type__c, Queue_Name__c — the fields needed.
  3. FROM Case_Routing_Rule__mdt — the object.
  4. ]; — closes the query — critically, this runs once per transaction, at the top of the handler method, following the same "collect, then act" instinct from Module 25.

Building a fast lookup key

Map<String, String> queueByPriorityAndType = new Map<String, String>();

for (Case_Routing_Rule__mdt rule : rules) {
    String key = rule.Priority__c + '|' + rule.Case_Type__c;
    queueByPriorityAndType.put(key, rule.Queue_Name__c);
}
  1. Map<String, String> queueByPriorityAndType = new Map<String, String>(); — the lookup, keyed by a composite string.
  2. (blank line)
  3. for (Case_Routing_Rule__mdt rule : rules) { — loops over the rules, in memory.
  4. String key = rule.Priority__c + '|' + rule.Case_Type__c; — combining Priority__c and Case_Type__c into a single composite key (Module 16's Map lesson, applied with a small trick: concatenating two values into one key).
  5. queueByPriorityAndType.put(key, rule.Queue_Name__c); — stores the queue under that key.
  6. } — closes the loop.

This lets every subsequent lookup be a single, instant Map.get() instead of looping through the rules list again for every Case.

Matching a Case against the rules

public void beforeInsert(List<Case> newCases) {
    // ... field-access check from the previous lesson ...

    Map<String, String> queueByPriorityAndType = buildRoutingLookup();

    for (Case c : newCases) {
        String key = c.Priority + '|' + c.Type;
        if (queueByPriorityAndType.containsKey(key)) {
            c.Assigned_Queue__c = queueByPriorityAndType.get(key);
        }
    }
}

private Map<String, String> buildRoutingLookup() {
    List<Case_Routing_Rule__mdt> rules = [SELECT Priority__c, Case_Type__c, Queue_Name__c FROM Case_Routing_Rule__mdt];
    Map<String, String> lookup = new Map<String, String>();
    for (Case_Routing_Rule__mdt rule : rules) {
        lookup.put(rule.Priority__c + '|' + rule.Case_Type__c, rule.Queue_Name__c);
    }
    return lookup;
}
  1. public void beforeInsert(List<Case> newCases) { — the entry point.
  2. // ... field-access check from the previous lesson ... — unchanged from before.
  3. (blank line)
  4. Map<String, String> queueByPriorityAndType = buildRoutingLookup(); — the lookup is built once.
  5. (blank line)
  6. for (Case c : newCases) { — loops over the new Cases.
  7. String key = c.Priority + '|' + c.Type; — builds the same kind of composite key.
  8. if (queueByPriorityAndType.containsKey(key)) { — checks the lookup.
  9. c.Assigned_Queue__c = queueByPriorityAndType.get(key); — assigns the matching queue, one Map.get() each, entirely in memory.
  10. } — closes the if.
  11. } — closes the loop.
  12. } — closes the method.
  13. (blank line)
  14. private Map<String, String> buildRoutingLookup() { — the helper.
  15. List<Case_Routing_Rule__mdt> rules = [SELECT Priority__c, Case_Type__c, Queue_Name__c FROM Case_Routing_Rule__mdt]; — the one query.
  16. Map<String, String> lookup = new Map<String, String>(); — the lookup being built.
  17. for (Case_Routing_Rule__mdt rule : rules) { — loops over the rules.
  18. lookup.put(rule.Priority__c + '|' + rule.Case_Type__c, rule.Queue_Name__c); — stores each one.
  19. } — closes the loop.
  20. return lookup; — hands back the completed lookup.
  21. } — closes the helper.

However many Cases there are in newCases, this is exactly Module 25's bulkification discipline, now applied to configuration data instead of database records.

Exercise

Given Priority = 'High' and Type = 'Problem' on a Case, build the composite lookup key the same way buildRoutingLookup does.

Show hint

c.Priority + '|' + c.Type

Salesforce: ○ Not connected Connect
APEX

Execution Results

Run your code to see the result.

Build Configurable Business Rules (Custom Metadata) Quiz

1. Why is Case_Routing_Rule__mdt queried once per transaction rather than once per Case?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

This lesson reads the configurable routing rules from custom metadata and builds a fast lookup structure, so the actual per-Case matching (next lesson) never needs to search the rules list repeatedly.