- リンクを取得
- ×
- メール
- 他のアプリ
SalesforceでRecord Typeを動的に取得および利用する方法
Salesforceでは、Record Typeを正確に取得するための戦略が重要です。特にAppExchangeアプリのような強力なアプリケーションを開発する際には、IDやNameを直接参照するのではなく、DeveloperNameを使用してRecord Typeを識別することが推奨されます。以下に、Record Typeを動的に取得し、環境やユーザー設定に依存しない方法を詳しく説明します。
1. なぜDeveloperNameを使用するのか
- Idの問題: Record TypeのIDは環境ごとに異なるため、特定のIDに依存するコードは移植性がありません。
- Nameの問題: Nameはユーザーの言語やローカライズ設定に基づいて変化するため、信頼できる識別子として使用できません。
- DeveloperNameの利点: 変更不可能な一意の識別子であり、どの環境でも同じ値を保持します。
2. 動的なRecord Type取得メソッド
以下は、指定したオブジェクトの利用可能なRecord TypeをDeveloperNameで動的に取得するユーティリティメソッドの例です。このメソッドはキャッシュを活用して効率を向上させています。
- public class Utils {
- // Record types cache
- private static Map<Schema.SObjectType, Map<String, Id>> rtypesCache;
- private static List<SObject> results;
- static {
- rtypesCache = new Map<Schema.SObjectType, Map<String, Id>>();
- results = new List<SObject>();
- }
- /**
- * 指定されたオブジェクトタイプの利用可能なRecordTypeを取得する
- * @param token Schema.SObjectType
- * @return Map<String, Id> DeveloperNameをキーとするRecordType IDのマップ
- */
- public static Map<String, Id> getRecordTypeMapForObjectGeneric(Schema.SObjectType token) {
- // キャッシュ確認
- Map<String, Id> mapRecordTypes = rtypesCache.get(token);
- if (mapRecordTypes != null) {
- return mapRecordTypes;
- }
- mapRecordTypes = new Map<String, Id>();
- rtypesCache.put(token, mapRecordTypes);
- // Describe情報を取得
- Schema.DescribeSObjectResult obj = token.getDescribe();
- // RecordTypeをSOQLで取得
- if (results.isEmpty()) {
- String soql = 'SELECT Id, DeveloperName, sObjectType FROM RecordType WHERE IsActive = TRUE';
- try {
- results = Database.query(soql);
- } catch (Exception ex) {
- results = new List<SObject>();
- }
- }
- // RecordTypeInfoを取得し、ユーザーに利用可能なものをフィルタリング
- Map<Id, Schema.RecordTypeInfo> recordTypeInfos = obj.getRecordTypeInfosByID();
- for (SObject rt : results) {
- if (recordTypeInfos.containsKey(rt.Id) && recordTypeInfos.get(rt.Id).isAvailable()) {
- mapRecordTypes.put(String.valueOf(rt.get('DeveloperName')), rt.Id);
- }
- }
- return mapRecordTypes;
- }
- }
3. 使用例
以下のコードは、`Account`オブジェクトのRecord Typeを動的に割り当てる例です。
- // Utilsクラスを使用してAccountのRecordTypeを取得
- Map<String, Id> accountTypes = Utils.getRecordTypeMapForObjectGeneric(Account.SObjectType);
- // 各RecordTypeのDeveloperNameとIdをデバッグ出力
- for (String developerName : accountTypes.keySet()) {
- System.debug('RecordType DeveloperName: ' + developerName + ', Id: ' + accountTypes.get(developerName));
- }
- // 特定の条件に基づいてRecordTypeを利用
- if (accountTypes.containsKey('Really_Stinking_Big_Account')) {
- System.debug('RecordType "Really_Stinking_Big_Account" is available with Id: ' + accountTypes.get('Really_Stinking_Big_Account'));
- } else {
- System.debug('RecordType "Really_Stinking_Big_Account" is not available.');
- }
4. この方法の利点
- 移植性の高さ: DeveloperNameを使用することで、どの環境でも正確にRecord Typeを特定可能。
- ユーザーや環境に依存しない: `isAvailable`プロパティを活用して、実行中のユーザーに利用可能なRecord Typeのみを使用。
- AppExchange対応: 動的SOQLを利用するため、Record TypeをサポートしないProfessional EditionやGroup Editionにも対応。
- パフォーマンス: キャッシュを利用してクエリ回数を削減。
まとめ
このアプローチにより、Salesforceアプリは柔軟性と堅牢性を備えた設計が可能になります。特に複雑な権限管理や多言語対応が求められる場合に効果的です。
コメント
コメントを投稿