LoginSignup
6
8

More than 5 years have passed since last update.

DescribeSObjectResultの取り方で結果が異なる

Posted at

はじめに

Apexで開発していく中で、使用頻度が上位にくる(かもしれない)クラスとしてSchema.DescribeSObjectResultが挙げられます。

さて、このクラスを取得する方法によって、結果が異なることがありました、ということでいくつか試してみたいと思います。

DescribeSObjectResultの取得パターン

さて、DescribeSObjectResultを取得するのに、3パターンほど思い浮かぶかと思います。(以下Accountオブジェクトを対象にしてます)

①SObjectクラスからトークンを取得しながら...

Schema.DescribeSObjectResult d = Account.sObjectType.getDescribe();

②Schemaクラスから対象オブジェクトのトークンを取得しながら...

Schema.DescribeSObjectResult d = Schema.getGlobalDescribe().get('Account').getDescribe();

③Schemaクラスから取得...

Schema.DescribeSObjectResult d = Schema.describeSObjects(new List<String>{'Account'})[0];

全て、AccountオブジェクトのDescribe Informationを取得するだけのコードで、特に変わったこともない(つもり)です。

さて、ココでAccountオブジェクトへの作成、編集、削除権限がないユーザで、上記コードを実行してみましょう。

作成、編集、削除権限のないユーザで実行してみる

※以下のコードを試す場合には、test method内で実行ください

List<Profile> profiles = [Select Id From Profile Where Name IN ('Read Only','参照のみ')];

Profile p = profiles[0];
User testUser = new User(
  alias = 'hogehoge',
  email = 'smith@salesforce.com',
  emailencodingkey = 'UTF-8',
  lastname = 'smith',
  languagelocalekey = 'en_US',
  localesidkey = 'en_US',
  profileid = p.Id,
  timezonesidkey = 'America/Los_Angeles',
  username = 'smith@salesforce.com.forsample'
);

System.runAs(testUser){

  Schema.DescribeSObjectResult d1 = Account.sObjectType.getDescribe();
  System.assertEquals(d1.isAccessible(), true);
  System.assertEquals(d1.isCreateable(), false);
  System.assertEquals(d1.isDeletable(), false);
  System.assertEquals(d1.isUpdateable(), false);

  Schema.DescribeSObjectResult d2 = Schema.getGlobalDescribe().get('Account').getDescribe();
  System.assertEquals(d2.isAccessible(), true);
  System.assertEquals(d2.isCreateable(), false);
  System.assertEquals(d2.isDeletable(), false);
  System.assertEquals(d2.isUpdateable(), false);

  Schema.DescribeSObjectResult d3 = Schema.describeSObjects(new List<String>{'Account'})[0];
  System.assertEquals(d3.isAccessible(), true);
  System.assertEquals(d3.isCreateable(), false);
  System.assertEquals(d3.isDeletable(), false);
  System.assertEquals(d3.isUpdateable(), false);

}

上記のコードを実行してみると、

System.assertEquals(d3.isCreateable(), false);

の箇所にて、

System.AssertException: Assertion Failed: Expected: true, Actual: false

というエラーが発生します。上2つの方法で取得した結果と異なりました。

Schema.describeSObjects(List)のリファレンスを見ると、【使用方法】には

このメソッドは、Schema.sObjectType トークンの getDescribe メソッドと類似しています。getDescribe メソッドと異なり、このメソッドでは sObject 型を動的に指定して、複数の sObject を一度に記述できます。

最初に getGlobalDescribe をコールして組織のすべてのオブジェクトのリストを取得します。その後リスト内を反復処理し、describeSObjects を使用して個々のオブジェクトのメタデータを取得します。

とあります。
"リスト内を反復処理し...個々のオブジェクトのメタデータを取得します" といった中で、メタデータ取得に関しては、システム権限で実行されてしまうのだろうと推測します。
(そのため、期待する結果が得られなかった、と)

さいごに

結局のところ、Schema.DescribeSObjectResultを取得したいときには、Schema.describeSObjects(List<String>)を使わない方が無難だよ、ということでしょうか。

(システム管理者権限でしか使わない、という前提があれば話は別ですが)

しかし、気付きにくい違いだったなぁ...と。(苦笑)

6
8
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
6
8