ApexSensei

Drills › Automate with triggers

Keep a Contact count on Account

Automate with triggers · Advanced · 25 min · Runs in your Salesforce Developer org · Apex Path

Scenario. Account managers want to see how many Contacts each Account has without running a report. The org has no custom field for it, so the count goes in the Employees field.

Write a Contact trigger that counts the Contacts on each Account again after every insert, update, delete and undelete, with one aggregate query and one update.

What you will learn

A rollup counts children on a parent. Use an aggregate query, which counts rows for you, not add/subtract 1.

for (AggregateResult ar : [
    SELECT AccountId, COUNT(Id) total
    FROM Contact GROUP BY AccountId
]) {
    Id parentId = (Id) ar.get('AccountId');
    Integer n = (Integer) ar.get('total');
}

Aggregate columns come back as Object — cast each. The drill borrows NumberOfEmployees.

Gotcha. An Account whose last Contact left returns no row. Set it to 0 yourself.

The task

Write the Contact trigger so each Account's NumberOfEmployees always equals the number of Contacts on that Account.

Examples:

  • an Account set to 7 gets 3 new Contacts → 3 (the count replaces the old number)
  • a Contact moves from Account A (2 Contacts) to Account B (1 Contact) → A is 1 and B is 2
  • the last Contact on an Account is deleted → 0, and undeleting it → 1

Requirements:

  1. Keep all four events from the starter header.
  2. Collect the AccountIds from Trigger.new and Trigger.old in one Set<Id>, and skip nulls. When a Contact moves, that gives you both the old and the new Account.
  3. Count with one aggregate query: COUNT(Id) for the Accounts in the Set, GROUP BY AccountId.
  4. Set every Account in the Set to 0 first, then fill in the counts from the query.
  5. Update the Accounts once, after the loops.

Starter code

trigger AS_CBF9D5C38E34_ContactCount on Contact (
    after insert,
    after update,
    after delete,
    after undelete
) {
}

When it passes

After any insert, move, delete or undelete, NumberOfEmployees on each affected Account equals its Contact count. An Account whose last Contact leaves shows 0, and 200 Contacts cost the same queries and DML as 2.

Try this drill free

You write the Apex yourself. ApexSensei runs it and tells you what passed and what did not.

‹ Block deleting Accounts with open deals