🐴

Salesforce:(memo)Apexで参照項目をたどることはできるのか

2021/01/27に公開

疑問

オブジェクトとして渡された値から参照項目をたどることは可能なのか

結論

sOQL使って値をとってきなさい。

参照項目をたどって項目を更新するApexトリガのサンプル

サンプルソース

// Apex Code 演習5-1
//
// 内定(Offer__c)の新規追加or更新→申込(Job_Application__c)の状況を変更
//
// トリガが複数存在する場合、実行される順番は任意
// ただしSalesforceがいうには現時点での実装はトリガ名の昇順らしい
trigger OfferTrigger on Offer__c (after insert, after update) {

 // 申込リスト生成
 List<Job_Application__c> jobApps = new List<Job_Application__c>();

 // トリガ対象の内定レコードに紐づく申込レコードの名前を取得し
 // 内定リストとして入手する
 for(List<Offer__c> offers:
  [select
   // Joinされる場合は
   // 内定オブジェクト上に定義されている関連を使用して
   // 表現する
   // 内定(Offer__c)に関連付けされている親である
   // 申込(Job_Application__c)の項目nameをさす
   job_application__r.name
  // 起点となるオブジェクトを1つだけ指定する
  from offer__c
  // 内定(Offer__c)のidがトリガ対象レコードのIDに含まれている
  where id IN :Trigger.newMap.keySet()]){

  // フェッチされた内定リストを1件づつ処理するループ
  for(Offer__c offer:offers){

   // 内定レコードに紐づく申込レコードのステージを
   // Offer Extendedに変更
   offer.job_application__r.stage__c = 'Offer Extended';

   // 内定レコードに紐づく申込レコードのステータスを
   // Holdに変更
   offer.job_application__r.status__c = 'Hold';

   // 内定リストに追加
   jobApps.add(offer.job_application__r);
  }
 }

 // 内定リストに1件以上データがある場合
 if (jobApps.size() > 0){
  try{
   // 内定リストに格納されているレコードを更新し
   // 結果を取得する
   // 失敗したレコードがある場合でも処理を継続する
   // Databaseメソッドの利点の一つとして結果をSaveResult
   // クラスインスタンス群として取得できる点にある
   Database.SaveResult[] saveResults = 
    Database.update(jobApps,false);

   // エラーとなった件数をカウントする変数
   Integer x = 0;
   // 更新結果を1件づつ処理するループ
   for(Database.SaveResult result:saveResults){
    // 更新失敗した場合
    if(!result.isSuccess()){
     // エラー情報を取得
     Database.Error err =
      result.getErrors()[0];
     // デバッグログへ書き出し
     System.debug(
     'Unable to update Job Application, ' +
     jobApps[x].name +
     '.  Error:'+ err.getMessage());
    }
    x++;
   }
  // 例外発生時処理
  } catch (Exception e){
   // 例外情報をデバッグログへ出力し、処理継続
   System.debug('error updating job applications:' + e);
  }
 }
}

→トリガーされたレコードのオブジェクトから参照関係のレコードをsOQL叩いて取得している。

参考にしたページ

[Salesforce]参照関係にあるオブジェクトをSOQLで取得する - dackdive's blog

[Apexトリガ]処理対象のレコードを参照する方法は?

理解した後に読むとすげーわかりやすい…w

ただし、トリガでは参照関係を辿って、
参照先の情報を取得することはできないので注意が必要です。
以下のような実装はできません。
例)
取引先に対するApexトリガで、参照関係にある取引先責任者の名前は辿れない。

List<Account> accountList = Trigger.new;
for(Account ac : accountList) {
    String sContactName = ac.contact.name; 
}

どうしても参照関係を辿りたい場合はSOQLを使用してください。

Discussion