before vs after
Cuándo escribir la lógica antes de que el registro se guarde y cuándo después. La regla cabe en una línea: si cambias el mismo registro, before; si tocas otros, after.
✓ En esta sub-lección
- 01Decidir entre before y after según lo que tiene que hacer el trigger.
- 02Cambiar campos del propio registro en before, sin consultas ni DML.
- 03Crear registros relacionados en after, usando el Id recién generado y un solo DML.
La nutria: ¿Te acuerdas? · Repaso de la lección 2
En un trigger before update, ¿cómo lees el StageName que tenía antes la oportunidad opp?
En la lección anterior viste que Trigger.new se puede cambiar en before y no en after. No es una regla caprichosa: sale directamente de en qué momento del guardado se ejecuta cada uno. Entender ese momento te dice, casi siempre, qué evento elegir.
La nutria: El paralelo de Admin
EL FLOW QUE MIGRAS HACÍA… · aciertos 0/0
Si la cuenta nueva llega sin Rating, ponerle 'Warm'.
before
sin Id en insert · cambias el propio registro
💾
se guarda · nace el Id
after
Id listo · Trigger.new de solo lectura
Paso 1 de 6
¿Dónde lo pondrías?
before: cambiar el propio registro, gratis
En before, el registro está en camino hacia la base de datos pero todavía no ha llegado. Si le cambias un campo, ese cambio viaja con él. No hace falta update, y no debes hacerlo: el guardado ya está en marcha. Es el sitio para rellenar valores por defecto, normalizar textos (el trim y toUpperCase del Módulo 1) o calcular un campo a partir de otros.
trigger LeadClean on Lead (before insert, before update) {
for (Lead l : Trigger.new) {
if (l.Company != null) {
l.Company = l.Company.trim();
}
if (String.isBlank(l.LeadSource)) {
l.LeadSource = 'Web';
}
}
// ni una consulta, ni un DML: el guardado ya está en marcha
}after: el Id existe y puedes tocar otros registros
En after, el registro ya se ha escrito (aunque todavía no se ha confirmado). Eso trae dos cosas. Primero, en insert ya tiene Id, así que puedes crear hijos que apunten a él: tareas, contactos, líneas. Segundo, Trigger.new pasa a ser de solo lectura: el registro ya se escribió y cambiarle un campo en memoria no serviría de nada. Si necesitas modificar otros registros, lo haces como en el Módulo 4: construyes una lista y haces un solo DML.
trigger AccountOnboarding on Account (after insert) {
List<Task> tasks = new List<Task>();
for (Account a : Trigger.new) {
tasks.add(new Task(
WhatId = a.Id, // el Id ya existe
OwnerId = a.OwnerId,
Subject = 'Llamada de bienvenida',
ActivityDate = Date.today().addDays(3)
));
}
insert tasks; // un DML para todo el lote
}El error típico: arreglar en after lo que era de before
Como en after no puedes cambiar Trigger.new, hay quien consulta los mismos registros y les hace update. Funciona, pero es el peor de los mundos: gasta una consulta y un DML que en before no necesitabas, el registro se guarda dos veces, y ese segundo update vuelve a disparar el trigger de update. Es el origen clásico de la recursión de la lección 5.
| Quieres… | Evento | ¿DML? |
|---|---|---|
| Rellenar o normalizar un campo del mismo registro | before | No |
| Calcular un campo a partir de otros del mismo registro | before | No |
| Rellenar un campo con datos del padre (cuenta, propietario) | before | No (pero sí una consulta) |
| Crear hijos que necesitan el Id del registro | after | Sí, uno |
| Actualizar el padre u otros registros | after | Sí, uno |
La nutria: Tus flows y tu Apex comparten los mismos límites
La nutria: ¿Y por qué no un Flow? Porque Account ya tiene trigger