Skip to main content

Información general sobre desencadenadores de Apex

Objetivos de aprendizaje

Después de completar esta unidad, podrá:

  • Escribir un desencadenador para un objeto de Salesforce.
  • Utilizar variables de contexto de desencadenadores.
  • Llamar a un método de clase desde un desencadenador.
  • Usar el método addError() de sObject en un desencadenador para restringir las operaciones de guardado.
Nota

Nota

¿Su idioma de aprendizaje es español? Comience el reto en un Trailhead Playground en español y utilice las traducciones proporcionadas entre paréntesis para navegar. Copie y pegue solo los valores en inglés, ya que las validaciones del reto se basan en los datos en inglés. Si no aprueba el reto en su organización en español, le recomendamos que (1) cambie la configuración regional a Estados Unidos, (2) cambie el idioma a inglés, siga las instrucciones descritas aquí y, a continuación, (3) vuelva a hacer clic en el botón Check Challenge (Comprobar el reto).

Consulte la insignia Trailhead en su idioma para obtener más información sobre cómo aprovechar la experiencia de Trailhead en otros idiomas.

Antes de comenzar

Los desencadenadores de Apex son útiles, divertidos y estupendos. En este módulo aprenderá a empezar a utilizarlos, pero también haremos referencia a otras funciones de Salesforce para demostrar el poder de los desencadenadores de Apex. Para sacar el máximo partido de este módulo, le recomendamos encarecidamente que eche un vistazo a estos otros primero:

Escritura de desencadenadores de Apex

Los desencadenadores de Apex permiten realizar acciones personalizadas antes o después de eventos para registros en Salesforce, como inserciones, actualizaciones o eliminaciones. Del mismo modo que los sistemas de bases de datos admiten desencadenadores, Apex permite el uso de desencadenadores para la gestión de registros.

Normalmente, los desencadenadores se usan para realizar operaciones basadas en condiciones específicas, modificar registros relacionados o impedir determinadas operaciones. Puede usar desencadenadores para realizar cualquier operación admitida en Apex, lo que incluye la ejecución de SOQL y DML o la llamada a métodos Apex personalizados.

Use desencadenadores para realizar tareas que no se pueden realizar con herramientas interactivas (apuntar y hacer clic) en la interfaz de usuario de Salesforce. Por ejemplo, si va a validar un valor de campo o actualizar un campo de un registro, use reglas y flujos de validación. Utilice desencadenadores de Apex si el rendimiento y la escala son importantes, si su lógica es demasiado compleja para herramientas de apuntar y hacer clic o si está ejecutando operaciones que consumen mucho rendimiento de la CPU.

Se pueden definir desencadenadores para objetos estándar de nivel superior, como una cuenta o un contacto, objetos personalizados y determinados objetos secundarios estándar. Los desencadenadores se activan de forma predeterminada al crearlos. Salesforce activa automáticamente desencadenadores cuando se producen eventos de base de datos específicos.

Sintaxis de desencadenadores

La sintaxis de una definición de desencadenador es distinta de la sintaxis de una definición de clase. La definición de un desencadenador empieza por la palabra clave trigger. A continuación, le siguen el nombre del desencadenador, el objeto de Salesforce con el que está asociado el desencadenador y las condiciones en las que este se activa. Un desencadenador tiene la siguiente sintaxis:

trigger TriggerName on ObjectName (trigger_events) {
   code_block
}

Para ejecutar un desencadenador antes o después de operaciones de inserción, actualización, eliminación y recuperación, especifique varios eventos de desencadenador en una lista separada por comas. Los eventos que se pueden especificar son:

  • before insert (antes de insertar)
  • before update (antes de actualizar)
  • before delete (antes de eliminar)
  • after insert (después de insertar)
  • after update (después de actualizar)
  • after delete (después de eliminar)
  • after undelete (después de recuperar)

Ejemplo de desencadenador

Este desencadenador sencillo se activa antes de insertar una cuenta y escribe un mensaje en el registro de depuración.

  1. En Developer Console, seleccione File (Archivo) | New (Nuevo) | Apex Trigger (Desencadenador de Apex).
  2. Escriba HelloWorldTrigger como nombre del desencadenador y, a continuación, seleccione la cuenta para sObject. Haga clic en Submit (Enviar).
  3. Sustituya el código predeterminado por lo siguiente:
trigger HelloWorldTrigger on Account (before insert) {
	System.debug('Hello World!');
}
  1. Para guardar, pulse Ctrl+S.
  2. Para probar el desencadenador, cree una cuenta.
    • Haga clic en Debug (Depurar) | Open Execute Anonymous Window (Abrir ventana de ejecución anónima).
    • En la ventana nueva, agregue lo siguiente y, a continuación, haga clic en Execute (Ejecutar).
Account a = new Account(Name='Test Trigger');
insert a;
  1. En el registro de depuración, busque la declaración Hello World!. En el registro se muestra además que el desencadenador se ha ejecutado.

Tipos de desencadenadores

Hay dos tipos de desencadenadores.

  • Los desencadenadores previos se usan para actualizar o validar valores de registro antes de guardarlos en la base de datos.
  • Los desencadenadores posteriores se usan para acceder a los valores de campo establecidos por el sistema (por ejemplo, el campo Id o LastModifiedDate de un registro) y aplicar cambios a otros registros. Los registros que activan el desencadenador posterior son de solo lectura.

Uso de variables de contexto

Para acceder a los registros que activan el desencadenador, use variables de contexto. Por ejemplo, Trigger.new contiene todos los registros insertados en desencadenadores de tipo insert o update. Trigger.old proporciona la versión anterior de sObjects antes de actualizarlos en desencadenadores update o una lista de sObjects eliminados en desencadenadores delete. Los desencadenadores se pueden activar cuando se inserta un registro o cuando se insertan numerosos registros de forma masiva mediante la API o Apex. Por consiguiente, las variables de contexto, como Trigger.new, pueden contener solo un registro o varios registros. Puede iterar en Trigger.new para obtener cada sObject individual.

Este ejemplo es una versión modificada del desencadenador de ejemplo HelloWorldTrigger. Itera en cada cuenta mediante un bucle for y actualiza el campo Description (Description) en cada caso.

trigger HelloWorldTrigger on Account (before insert) {
    for(Account a : Trigger.new) {
        a.Description = 'New description';
    }
}
Nota

El sistema guarda los registros que han activado el desencadenador previo una vez que el desencadenador finaliza la ejecución. Puede modificar los registros en el desencadenador sin llamar de forma explícita a una operación de inserción o actualización de DML. Si realiza declaraciones DML en estos registros, obtiene un error.

Algunas otras variables de contexto devuelven un valor booleano para indicar si el desencadenador se ha activado debido a una actualización o a algún otro evento. Estas variables son de utilidad cuando un desencadenador combina varios eventos. Por ejemplo:

trigger ContextExampleTrigger on Account (before insert, after insert, after delete) {
    if (Trigger.isInsert) {
        if (Trigger.isBefore) {
            // Process before insert
        } else if (Trigger.isAfter) {
            // Process after insert
        }
    }
    else if (Trigger.isDelete) {
        // Process after delete
    }
}

La siguiente tabla ofrece una lista completa de todas las variables de contexto disponibles para desencadenadores.

Variable

Uso

isExecuting

Devuelve true si el contexto actual para el código Apex es un desencadenador, pero no una página de Visualforce, un servicio web o una llamada a API executeanonymous().

isInsert

Devuelve true si este desencadenador se activó debido a una operación de inserción en la interfaz de usuario de Salesforce, Apex o la API.

isUpdate

Devuelve true si este desencadenador se activó debido a una operación de actualización en la interfaz de usuario de Salesforce, Apex o la API.

isDelete

Devuelve true si este desencadenador se activó debido a una operación de eliminación en la interfaz de usuario de Salesforce, Apex o la API.

isBefore

Devuelve true si este desencadenador se ha activado antes de que se haya guardado cualquier registro.

isAfter

Devuelve true si este desencadenador se ha activado después de que se hayan guardado todos los registros.

isUndelete

Devuelve true si este desencadenador se ha activado después de recuperar un registro desde la papelera. Esta recuperación puede producirse después de una operación de recuperación desde la interfaz de usuario de Salesforce, Apex o la API.

new

Devuelve una lista de versiones nuevas de registros de sObject.

Esta lista de sObject solamente está disponible en desencadenadores insert, update y undelete, y los registros únicamente se pueden modificar en desencadenadores before.

newMap

Asignación de Id. a las versiones nuevas de los registros de sObject.

Esta asignación solo está disponible en los desencadenadores before update, after insert, after update y after undelete.

old

Devuelve una lista de versiones anteriores de registros de sObject.

Esta lista de sObjects solo está disponible en los desencadenadores update y delete.

oldMap

Asignación de Id. a las versiones anteriores de los registros de sObject.

Esta asignación solo está disponible en los desencadenadores update y delete.

operationType

Devuelve una enumeración de tipo System.TriggerOperation correspondiente a la operación actual.

Los posibles valores de la enumeración System.TriggerOperation son: BEFORE_INSERT, BEFORE_UPDATE, BEFORE_DELETE, AFTER_INSERT, AFTER_UPDATE, AFTER_DELETE, y AFTER_UNDELETE. Si varía su lógica de programación basándose en diferentes tipos de desencadenadores, considere el uso de la declaración switch con diferentes combinaciones de estados de enumeración de ejecución de desencadenador únicos.

size

Número total de registros en una invocación de desencadenadores (tanto anteriores como nuevos).

Llamada a un método de clase desde un desencadenador

Puede llamar a métodos de utilidad públicos desde un desencadenador. La llamada a métodos de otras clases permite la reutilización de código, reduce el tamaño de los desencadenadores y mejora el mantenimiento del código Apex. Además, permite el uso de programación orientada a los objetos.

En el siguiente ejemplo de desencadenador se muestra cómo llamar a un método estático desde un desencadenador. Si el desencadenador se ha activado debido a un evento de inserción, en el ejemplo se llama al método estático notifyUsers() de la clase CustomContactNotification. Este método de utilidad envía una notificación personalizada a los usuarios de Salesforce definidos en el desencadenador. La notificación contiene el número de registros de contacto insertado.

Nota

Para este ejemplo, cree una notificación personalizada. Las notificaciones personalizadas solo están disponibles en Lightning Experience. La creación y modificación de notificaciones requiere el permiso de usuario Customize Application (Personalizar aplicación). Para obtener más información, consulte Crear una notificación móvil o de escritorio.

  1. Cree una notificación de escritorio personalizada.
    • En Setup (Configuración), en el cuadro Quick Find (Búsqueda rápida), introduzca Notification Builder (Generador de notificaciones) y seleccione Custom Notifications (Notificaciones personalizadas).
    • Haga clic en New (Nueva).
    • En Custom Notification Name (Nombre de la notificación personalizada), introduzca New Contact Notification (Nueva notificación de contacto).
    • En API Name (Nombre de API), introduzca New_Contact_Notification.
    • En Supported Channels (Canales compatibles), seleccione Desktop (Escritorio).
    • Haga clic en Save (Guardar).
  2. En Developer Console, haga clic en File (Archivo) | New (Nuevo) | Apex Class (Clase de Apex).
  3. Introduzca CustomContactNotification y, a continuación, haga clic en OK (Aceptar).
  4. Sustituya el cuerpo de clase predeterminado por el ejemplo de clase CustomContactNotification.
public with sharing class CustomContactNotification {
    // Public method
    public static void notifyUsers(Set<String> recipientsIds, Integer recordCount) {
        

        // Get the ID for the custom notification type created in Setup
 		CustomNotificationType notificationType =
            [SELECT Id, DeveloperName
             FROM CustomNotificationType
             WHERE DeveloperName='New_Contact_Notification'];
        

        // Create a new custom notification
        Messaging.CustomNotification notification = new Messaging.CustomNotification();
        

        // Set the contents for the notification
        notification.setTitle('Trailhead Trigger Tutorial');
        notification.setBody(recordCount + ' contact(s) were inserted.');


        // Set the notification type and target
        notification.setNotificationTypeId(notificationType.Id);
        // '000000000000000AAA' is a dummy targetId value
        notification.setTargetId('000000000000000AAA');
        

       // Send the notification
       try {
           notification.send(recipientsIds);
           System.debug('Custom notification sent successfully.');
       }
       catch (Exception e) {
           System.debug('Problem sending notification: ' + e.getMessage());
        }
    }
}
  1. En Developer Console, seleccione File (Archivo) | New (Nuevo) | Apex Trigger (Desencadenador de Apex).
  2. Escriba ContactNotificationTrigger como nombre del desencadenador y, a continuación, seleccione Contact (Contacto) para el sObject. Haga clic en Submit (Enviar).
  3. Sustituya el código predeterminado por lo siguiente:
trigger ContactNotificationTrigger on Contact (after insert, after delete) {
    if (Trigger.isInsert) {
        Integer recordCount = Trigger.new.size();
        

        // Set the recipientIDs to the current user
        Set<String> recipientIDs = new Set<String>{UserInfo.getUserId()};
      

        // Call a utility method from another class
        CustomContactNotification.notifyUsers(recipientIDs, recordCount);
    }
    else if (Trigger.isDelete) {
        // Process after delete
    }
}
  1. Para guardar, pulse Ctrl+S.
  2. Para probar el desencadenador, cree un contacto.
    • Haga clic en Debug (Depurar) | Open Execute Anonymous Window (Abrir ventana de ejecución anónima).
    • En la ventana nueva, agregue lo siguiente y, a continuación, haga clic en Execute (Ejecutar).
Contact c = new Contact(LastName='Test Contact');
insert c;
  1. En el registro de depuración, compruebe si el desencadenador se ha activado. Al final del registro, busque el mensaje de depuración escrito mediante el método de utilidad: DEBUG|Custom notification sent successfully. (DEPURACIÓN|La notificación personalizada se ha enviado correctamente).
  2. Ahora, compruebe que ha recibido la notificación. Para abrir el panel Notification (Notificación), haga clic en Campana de notificación. Debería ver una notificación con el título "Trailhead Trigger Tutorial" (Tutorial de desencadenadores de Trailhead) y el cuerpo "1 contact(s) were inserted" (Se ha insertado un contacto).

Con el nuevo desencadenador, recibirá una notificación de escritorio personalizada cada vez que agregue uno o varios contactos.

Los desencadenadores se suelen usar para gestionar y acceder a registros relacionados con otros registros en el contexto del desencadenador (registros que activan el desencadenador).

Este desencadenador agrega una oportunidad relacionada para cada cuenta nueva o actualizada si no hay ninguna oportunidad asociada a la cuenta. El desencadenador realiza primero una consulta SOQL para obtener todas las oportunidades secundarias de las cuentas en las que se ha activado el desencadenador. A continuación, el desencadenador itera en la lista de sObjects en Trigger.new para obtener el sObject de cada cuenta. Si la cuenta no tiene ningún sObject de oportunidad relacionado, el bucle (for) crea uno. Si el desencadenador ha creado oportunidades, la declaración final las inserta.

  1. Agregue el siguiente desencadenador desde Developer Console (realice los pasos del ejemplo de HelloWorldTrigger, pero use AddRelatedRecord como nombre del desencadenador).

trigger AddRelatedRecord on Account(after insert, after update) {
    List<Opportunity> oppList = new List<Opportunity>();
    // Get the related opportunities for the accounts in this trigger
    Map<Id,Account> acctsWithOpps = new Map<Id,Account>(
        [SELECT Id,(SELECT Id FROM Opportunities) FROM Account WHERE Id IN :Trigger.new]);
    // Add an opportunity for each account if it doesn't already have one.
    // Iterate through each account.
    for(Account a : Trigger.new) {
        System.debug('acctsWithOpps.get(a.Id).Opportunities.size()=' + acctsWithOpps.get(a.Id).Opportunities.size());
        // Check if the account already has a related opportunity.
        if (acctsWithOpps.get(a.Id).Opportunities.size() == 0) {
            // If it doesn't, add a default opportunity
            oppList.add(new Opportunity(Name=a.Name + ' Opportunity',
                                       StageName='Prospecting',
                                       CloseDate=System.today().addMonths(1),
                                       AccountId=a.Id));
        }
    }
    if (oppList.size() > 0) {
        insert oppList;
    }
}
  1. Para probar el desencadenador, cree una cuenta en la interfaz de usuario de Salesforce y asígnele el nombre Apples & Oranges.
  2. En la lista relacionada de oportunidades de la página de la cuenta, busque la oportunidad nueva. El desencadenador ha agregado esta oportunidad automáticamente.
Nota

El desencadenador que ha agregado itera en todos los registros que forman parte del contexto del desencadenador (el bucle for itera en Trigger.new). No obstante, el bucle de este desencadenador podría ser más eficiente. En realidad no es necesario acceder a cada cuenta en el contexto de este desencadenador, sino solo a un subconjunto (cuentas sin oportunidades). En la siguiente unidad se describe cómo aumentar la eficiencia de este desencadenador. En la unidad Patrones de diseño de desencadenadores masivos, puede obtener información sobre cómo modificar la consulta SOQL para obtener solamente cuentas sin oportunidades. A continuación, puede aprender a iterar solamente en esos registros.

Uso de excepciones de desencadenadores

En ocasiones, es posible que necesite agregar restricciones para determinadas operaciones de base de datos, como impedir que los registros se guarden cuando se cumplen determinadas condiciones. Para evitar que los registros se guarden en un desencadenador, llame al método addError() del sObject en cuestión. El método addError() genera un error grave en el desencadenador. El mensaje de error se muestra en la interfaz de usuario y se registra.

El siguiente desencadenador impide la eliminación de una cuenta si esta tiene oportunidades relacionadas. De forma predeterminada, la eliminación de una cuenta provoca la eliminación en cascada de todos sus registros relacionados. Este desencadenador impide la eliminación en cascada de las oportunidades. Pruebe este desencadenador. Si ha ejecutado el ejemplo anterior, su organización tiene una cuenta llamada Apples & Oranges con una oportunidad relacionada. En este ejemplo se usa dicha cuenta.

  1. Use Developer Console para agregar el siguiente desencadenador.
trigger AccountDeletion on Account (before delete) {
    // Prevent the deletion of accounts if they have related opportunities.
    for (Account a : [SELECT Id FROM Account
                     WHERE Id IN (SELECT AccountId FROM Opportunity) AND
                     Id IN :Trigger.old]) {
        Trigger.oldMap.get(a.Id).addError(
            'Cannot delete account with related opportunities.');
    }
}
  1. En la interfaz de usuario de Salesforce, navegue hasta la página de la cuenta Apples & Oranges y haga clic en Delete (Eliminar).
  2. En el mensaje emergente de confirmación, haga clic en Aceptar.

Busque el error de validación con el mensaje de error personalizado Cannot delete account with related opportunities (No se puede eliminar la cuenta con oportunidades relacionadas).

  1. Desactive el desencadenador AccountDeletion. Si deja este desencadenador activado, no podrá revisar los aspectos complejos.
    • En Setup (Configuración), busque Apex Triggers (Desencadenadores de Apex).
    • En la página Apex Triggers (Desencadenadores de Apex), haga clic en Edit (Modificar) junto al desencadenador AccountDeletion.
    • Anule la selección de Is Active (Está activo).
    • Haga clic en Save (Guardar).
Nota

La llamada a addError() en un desencadenador revierte todo el conjunto de operaciones, excepto si se llama a DML masivo con una validez parcial.

  • Si una llamada a DML masivo en la API de Plataforma Lightning ha generado el desencadenador, el motor en tiempo de ejecución prescinde de los registros incorrectos. A continuación, el motor en tiempo de ejecución intenta el almacenamiento parcial de los registros que no han generado errores.
  • Si una declaración DML en Apex ha generado el desencadenador, cualquier error revierte toda la operación. No obstante, el motor en tiempo de ejecución sigue procesando cada registro de la operación para compilar una lista de errores exhaustiva.

Desencadenadores y llamadas

Apex permite hacer llamadas e integrar el código Apex con servicios web externos. Estos contactos de Apex con servicios web externos se denominan llamadas. Por ejemplo, puede hacer una llamada a un servicio de cotización para conocer las últimas cotizaciones. Al hacer una llamada desde un desencadenador, dicha llamada se debe hacer de forma asíncrona para que el proceso del desencadenador no le impida trabajar mientras espera la respuesta del servicio externo. La llamada asíncrona se realiza mediante un proceso en segundo plano y la respuesta se recibe cuando el servicio externo la devuelve.

Para hacer una llamada desde un desencadenador, llame a un método de clase que se ejecute de forma asíncrona. Este método se llama método futuro y se anota con @future(callout=true). Esta clase de ejemplo contiene el método futuro que hace la llamada.

Nota

En el ejemplo se usa dirección URL de extremo hipotética con fines ilustrativos. No puede ejecutar este ejemplo a menos que cambie el extremo a una URL válida y agregue un sitio remoto en Salesforce para su extremo.

public class CalloutClass {
    @future(callout=true)
    public static void makeCallout() {
        HttpRequest request = new HttpRequest();
        // Set the endpoint URL.
        String endpoint = 'http://yourHost/yourService';
        request.setEndPoint(endpoint);
        // Set the HTTP verb to GET.
        request.setMethod('GET');
        // Send the HTTP request and get the response.
        HttpResponse response = new HTTP().send(request);
    }
}

En este ejemplo se muestra el desencadenador que llama al método en la clase para hacer una llamada asíncrona.

trigger CalloutTrigger on Account (before insert, before update) {
    CalloutClass.makeCallout();
}

Esta sección es solo una descripción general de las llamadas y el objetivo no es proporcionar información detallada. Para obtener más información, consulte Invocación de llamadas utilizando Apex en la Guía del desarrollador de Apex.

Recursos

Comparta sus comentarios sobre Trailhead en la Ayuda de Salesforce.

Nos encantaría conocer su experiencia con Trailhead. Ahora puede acceder al nuevo formulario de comentarios cuando quiera desde el sitio de la Ayuda de Salesforce.

Más información Continuar para compartir comentarios