0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Apexトリガーの有効化/無効化切り替え処理を作る

Posted at

フローみたいにApexトリガーも有効化と無効化の切り替えを簡単にしたい!

ずっとやりたいな〜と思っていたことで、最近機会に恵まれたのでメモを残します。 

カスタムメタデータ型を作る

apex_trigger_onoff_01.png

有効化/無効化を制御するためのデータを保持するカスタムメタデータ型をいい感じの名前で作ります。

apex_trigger_onoff_02.png

トリガーイベント毎に切り替えたいので、イベント毎にチェックボックスを作ります。
このチェックボックスがTrueのときに有効、Falseのときに無効とします。

apex_trigger_onoff_03.png

事前にレコードを作っておきます。

有効化/無効化チェック処置を作る

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()をトリガーから呼び出して〆

参考にさせていただいたページ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?