Translate

2011年5月3日火曜日

レコードの追加更新時にApexトリガで重複チェックしてはじくサンプル

Apexトリガを使用する場合のよくあるパターンの一つに

重複チェックがある。



Salesforceのオンライン研修でも

レコード(見込み顧客)を追加する前に

ユーザにかならず重複チェックを

手動で行うように指導している。



とはいえ

営業担当者はIT弱者は少なくない(失礼)ので

自動でチェックさせてはじくようにしたい。



以下のサンプルは

Force.com開発者コース演習5-2のサンプルコード

である。





// Apex Code 演習5-2
// 応募者(Candidate)の重複防止
// 応募者(Candidate__c)が新規作成・更新直前→重複チェックApexクラス呼び出し
trigger CandidateKeyTrigger on Candidate__c (before insert, before update) {

// トリガ発生元となった応募者レコード群
private Candidate__c[] newCandidates = Trigger.new;
// 重複チェック
CandidateKey.hasCandidateDuplicates(newCandidates);
}


重複チェックなのでトリガとしては

追加更新の「直前」になるのだけど、

当然チェックしたレコードを格納させたくはない。



重複レコードをはじく方法として

以下のようにaddError()を使用する。

これが最大のポイントである。




// Apex Code 演習5-2
// 注意:
// 応募者の「姓」と「電子メールアドレス」を連結した文字列を使って
// 応募者の"名寄せ"を行っている
// 応募者(Candidate__c)オブジェクトの「unique_key__c」には
// 「LOWER(Last_Name__c & Email__c)」が設定されている
public class CandidateKey {

// 重複チェック処理
// 引数: candidates チェック対象の応募者レコード群
public static void hasCandidateDuplicates(Candidate__c[] candidates){

// unique_key__cとCandidate__cレコードのMap
Map<String,Candidate__c> candidateMap =
new Map<String,Candidate__c>();

// 応募者レコードループ
for(Candidate__c candidate:candidates) {
// 電子メールが設定されている場合
if (candidate.email__c != null){
// Map内の応募者レコードと重複している場合
if(candidateMap.containsKey(
candidate.unique_key__c))
// エラーメッセージを追加
candidate.addError(
'Duplicate LastName + Email found '+
'in batch');
else
// 重複がないのでMapへ追加
candidateMap.put(
candidate.unique_key__c,
candidate);
}
}

// Mapにレコードが存在する場合
if (!candidateMap.isEmpty()){
// Mapのレコードと重複するDB上の応募者レコードを取得
for(Candidate__c[] candidatesCheck:
[select unique_key__c
from Candidate__c
where unique_key__c IN
:candidateMap.keySet()]) {

// フェッチレコードループ
for(Candidate__c candidate:candidatesCheck) {
// 応募者レコードID
String currentCandidateId =
candidate.Id;

// Map内の重複レコードのIDが異なる場合
if(candidateMap.containsKey(
candidate.unique_key__c) &&
(currentCandidateId !=
candidateMap.get(
candidate.unique_key__c).Id)) {

// エラーメッセージ追加
candidateMap.get(
candidate.unique_key__c).
addError('Duplicate LastName' +
' + Email found in salesforc' +
'e(id: ' + candidate.id + ')');
}
}
}
}
}
}





このトリガはbeforeなので、

新規追加や更新される前の処理である。

addError()されたレコードは、

Database.insert() or Database.update()で呼び出された場合は

該当レコードは処理されず

画面呼び出しの場合は

addError()で渡された文字列が

画面の所定位置に表示され

こちらもDBは追加・更新されない。

0 件のコメント:

既存アプリケーションをK8s上でコンテナ化して動かす場合の設計注意事項メモ

既存アプリをK8sなどのコンテナにして動かすには、どこを注意すればいいか..ちょっと調べたときの注意事項をメモにした。   1. The Twelve Factors (日本語訳からの転記) コードベース   バージョン管理されている1つのコードベースと複数のデプロイ 依存関係 ...