フローみたいにApexトリガーも有効化と無効化の切り替えを簡単にしたい!
ずっとやりたいな〜と思っていたことで、最近機会に恵まれたのでメモを残します。
カスタムメタデータ型を作る
有効化/無効化を制御するためのデータを保持するカスタムメタデータ型をいい感じの名前で作ります。
トリガーイベント毎に切り替えたいので、イベント毎にチェックボックスを作ります。
このチェックボックスがTrueのときに有効、Falseのときに無効とします。
事前にレコードを作っておきます。
有効化/無効化チェック処置を作る
public without sharing class ApexTriggerUtil {
@TestVisible private ApexTriggerUtil() {} // コンストラクタ呼び出し禁止
/**
* トリガーイベント有効化フラグ取得
*/
public static Boolean isActiveEvent(System.TriggerOperation event, String triggerName) {
ApexTriggerSetting__mdt mdt = ApexTriggerSetting__mdt.getInstance(triggerName);
Boolean isActive = false;
switch on event {
when BEFORE_INSERT {
isActive = mdt?.IsBeforeInsert__c ?? false;
}
when BEFORE_UPDATE {
isActive = mdt?.IsBeforeUpdate__c ?? false;
}
when BEFORE_DELETE {
isActive = mdt?.IsBeforeDelete__c ?? false;
}
when AFTER_INSERT {
isActive = mdt?.IsAfterInsert__c ?? false;
}
when AFTER_UPDATE {
isActive = mdt?.IsAfterUpdate__c ?? false;
}
when AFTER_DELETE {
isActive = mdt?.IsAfterDelete__c ?? false;
}
when AFTER_UNDELETE {
isActive = mdt?.IsAfterUndelete__c ?? false;
}
when else {}
}
if (! isActive) System.debug(triggerName + ': ' + event + ' 無効化中');
return isActive;
}
}
staticメソッドのみなのでコンストラクタはprivateにして呼び出せないようにします。
トリガーハンドラ抽象クラスを作る
public abstract class TriggerHandler {
public void dispatch(String triggerName) {
// トリガー有効化チェック
if (! ApexTriggerUtil.isActiveEvent(Trigger.operationType, triggerName)) return;
switch on Trigger.operationType {
when BEFORE_INSERT {
this.beforeInsert();
}
when BEFORE_UPDATE {
this.beforeUpdate();
}
when BEFORE_DELETE {
this.beforeDelete();
}
when AFTER_INSERT {
this.afterInsert();
}
when AFTER_UPDATE {
this.afterUpdate();
}
when AFTER_DELETE {
this.afterDelete();
}
when AFTER_UNDELETE {
this.afterUndelete();
}
when else {}
}
}
protected virtual void beforeInsert() {}
protected virtual void beforeUpdate() {}
protected virtual void beforeDelete() {}
protected virtual void afterInsert() {}
protected virtual void afterUpdate() {}
protected virtual void afterDelete() {}
protected virtual void afterUndelete() {}
}
継承クラスをインスタンス化しない場合はabstract、インスタンス化する場合はvirtualをクラスにつけます。
今回は継承のみで単体では使わないのでabstractをつける。
各種イベントメソッドは継承先でオーバーライドするのでvirtualをつける。
dispatch()
はオーバーライドしないのでつけません。
トリガーイベントの判定前に先ほど作った有効化/無効化判定処理で無効だったらそのまま終了させる。
トリガーハンドラ継承クラスを作る
public class TestTriggerHandler extends TriggerHandler {
private List<Account> newList;
private List<Account> oldList;
private Map<Id, Account> newMap;
private Map<Id, Account> oldMap;
/**
* コンストラクタ
*/
public TestTriggerHandler() {
if (Trigger.new != null) this.newList = (List<Account>) Trigger.new;
if (Trigger.old != null) this.oldList = (List<Account>) Trigger.old;
if (Trigger.newMap != null) this.newMap = (Map<Id, Account>) Trigger.newMap;
if (Trigger.oldMap != null) this.oldMap = (Map<Id, Account>) Trigger.oldMap;
}
/**
* Before Insert
*/
public override void beforeInsert() {
/* Before Insert時の処理 */
}
/**
* Before Update
*/
public override void beforeUpdate() {
/* Before Update時の処理 */
}
}
トリガーを作る
trigger TestTrigger on Account (before insert, before update) {
new TestTriggerHandler().dispatch('TestTrigger');
}
抽象クラスで作ったdispatch()
をトリガーから呼び出して〆
参考にさせていただいたページ