yujiroのプログラミング

勉強内容をアウトプットし、サボらないようにする為のブログ

<DAY205>APEX トリガーについて

\ Follow me!! /

●9/14(土)
●学習日数 205日
●学習時間(本日)5時間
●累計学習時間 864.0時間
●一日あたりの平均学習時間 4.21時間

f:id:yujiro0320:20190904163314p:plain

トリガー

jqueryでいうセレクタ的な意味。
Salesforce のレコードに対するイベント (挿入、更新、削除) などを発火キーとして使用できる。
Apexで行えることは全てトリガーで行う事ができる。
トリガは、同じ処理を Salesforce が提供するポイント & クリック自動化ツールのいずれでも実行できないことが絶対確実である場合にのみ、最後の手段として使用します

使用するケースとしては、
(1)特定の条件に基づき操作を実行する場合
(2)関連レコードを変更する場合
(3)特定の操作の実行を制限する場合

トリガーの構文

クラスとは異なる。
トリガ定義の構文は、クラス定義の構文とは異なります。トリガ定義は、引き金 キーワードで開始します。その後に、トリガの名前、トリガが関連付けられている Salesforce オブジェクト、トリガを実行する条件が続きます。トリガの構文は次のとおりです。

trigger TriggerName on ObjectName (trigger_events) {
   code_block
}

簡単なトリガーを作成

trigger HelloWorldTrigger on Account (before insert) {
	System.debug('Hello World!');
}

トリガーが発動するタイミングは2種類ある

before トリガ

レコードがデータベースに保存される前にレコードの値を更新または検証する場合

after トリガ

システムによって設定された項目値 にアクセスする場合や、他のレコードの変更に影響を与える場合に使用します。
after トリガを実行するレコードは参照のみです。

指定できるトリガイベント
before insert
before update
before delete
after insert
after update
after delete
after undelete

コンテキスト変数

(例)
for で反復処理している。
取引先オブジェクトが挿入される前を発火としている。
コンテキスト変数はnew。
Trigger.new

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

複数のイベントを発火とする場合もある

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
    }
}
トリガコンテキスト変数

トリガコンテキスト変数の表が参考文献にあるので、確認する。
覚えるまでは見返す機会が多そう

トリガからのクラスメソッドのコール

クラスメソッドを呼ぶこともできるよ。

記述は省略

関連レコードの追加

トリガーの役割のメイン!
この記述の場合は、取引先のデーターが更新または、新規で挿入された場合に、
ひもづく商談内容を更新すyるものである。

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;
    }
}

トリガの例外の使用


特定の条件を満たしたときはレコードが保存されないようにするなど、場合によっては特定のデータベース操作に制限を加える必要があることがあります。トリガにレコードが保存されないようにするには、問題の sObject で addError() メソッドをコールします。addError() メソッドは、トリガ内で致命的なエラーを生成します。このエラーメッセージがユーザインターフェースに表示され、ログに記録されます。

トリガとコールアウト

Apex を使用すると、外部 Web サービスへのコールが可能になり、Apex コードを外部 Web サービスと統合できるようになります。外部 Web サービスへの Apex コールをコールアウトといいます。たとえば、株価情報サービスへのコールアウトを実行して、最新の株価情報を取得できます。トリガからコールアウトを実行するときは、外部サービスからの応答を待機中に、トリガプロセスによって操作がブロックされないように、コールアウトを非同期に行う必要があります。非同期コールアウトをバックグラウンドプロセスで実行して、外部サービスから応答が返されたら受信します。
トリガからコールアウトを実行するには、非同期に実行するクラスメソッドをコールします。このようなメソッドを future メソッドといい、@future(callout=true) アノテーションが付加されます。次のクラスの例には、コールアウトを実行する future メソッドが含まれます。