みなさまこんにちは、某Platform Specialistのしょっさんなんですが、これは Salesforce Platform Advent Calendar 2020 5日目です。
今日は22日です。はい、すいません、イロイロあったんです、悟ってください。申し訳ない。
なお、4日目は @hanamizuki10 さんのSalesforce:ソフトフォン( Lightning Open CTI )の環境構築方法について、6日目は @laughingman さんの Open CTI で Lightning Message Service を使用してみる です。CTIに囲まれている私は、空気も読まずに「共有の直接設定」について説明します。
実はこれ重要です。試験に出るから覚えておけよー。
共有の直接設定って?
Salesforce のもつ、複雑かつ自由度の高い認可の仕組みの中で、個人的に不思議な機能があります。「共有の直接設定」です。
Salesforce のレコードは、"レコード所有者"および"その所有者よりもロールが上のユーザ"、"レコードのフルアクセスが許可されたユーザ"、"システム管理者"は、アクセス認可のないユーザに独自にアクセスを許可することができる仕組みです。例外中の例外を司る仕組みな気がします。しかも、「Classic
でしか」使えません。しかし、この自由度のおかげで、共有ルールやロール階層からはじかれているが、どうしても、なんとしてもこのレコードだけは見せてあげたい、編集させてあげたい、というわがままな意向をくんでくれる素晴らしい機能です。Classic
じゃないと使えませんが。
しかし、これ。ちょっとだけ難儀な部分があります。「所有者を変更すると、その所有者が共有したユーザのアクセス権が奪われる」のです。
こちらをご覧ください。「しょっさん」が「プラットフォーム」というユーザに対して、「共有の直接設定」を使って参照を許可したの図です
このときに「しょっさん」が所有者を他の「QP」さんへ変更したとします。すると、こう。
この仕組み自体の考え方には賛同できます。所有者が変わったときに、前任者が好き放題共有しているかもしれません。新しい所有者は、共有された彼らと仲が良いとは限りません。絶対に見せない意思を持っている可能性もあります。
しかし、世の中はそんなに殺伐としたものだけではありません。共有設定したユーザたちを残したい。そんな意向をくんであげてもいいじゃないですか。しかし、標準の機能では実装できません。どうしたものか。
そうだ、ボクたちには apex
があった。
Apex を使ったレコードの共有
Apex でもこの機能を利用することができます。Salesforce には、共有を管理するための「共有オブジェクト」があります。Apex では、この共有オブジェクトを直接操作することで、プログラムで自動的に共有を制御できます。お便利ですね。さすがApex(褒めてる)。
機能的には「共有の直接設定」と同様の機能が利用できるのですが、大きく異なるのは「共有の理由」をカスタマイズして設定できることです。
「どういうこと?」という感じですね。この「所有者変更により、共有されたユーザが一掃される原因」は「共有の理由がManual
だから」です。そういう仕様です。決め事です。大人の事情です。Classic
画面に表示される「共有」ボタンを使って「共有の直接設定」を行うと「共有の理由」を Manual
で共有します。画面上では「共有の直接設定」と出ていますね。所有者変更で、共有が削除されるトリガは、この「共有の理由が何か」なのです。
では、所有者を変更しても、共有設定を維持したい場合にはどうしたらいいか。それが「共有の理由をManual
以外にすればいい」ということなのです。そして、この共有理由をカスタマイズして設定できるのはApex
「だけ」です!!! Ω ΩΩ< な、なんだってー!! (正確に言うと、共有ルールや商談チームなどで割り当てられる「理由」もManual
以外の何かが設定されてます → 「共有の理解内の「共有の理由項目」を参照ください)
では、試しにやってみましょう。次の手順で設定します。
- 独自の Apex 共有の理由を作成する
- Apex を書く
シンプルですね! やってみましょう(๑•̀ㅂ•́)و✧
Apex 共有の理由を作成する
Classic
で、対象のオブジェクトの設定を表示します。下の方に「Apex 共有の理由」という関連リストがあります。ここで、自分の好きなApex
だけでつかえる「共有の理由」を作成できます。
「共有の理由」というくらいなので、本来は、どの Apex でどのような仕様に従ってその共有がなされたか、を示すものです。一つならまだしも、複数の共有仕様がやってくると、なぜそのユーザに共有されたかが分からなくなります。その「なぜ」を追跡できるように定義するんですね、素晴らしい。
そんなわけで試しに作ってみました。お試しなのでそのままの理由です。
この「理由名」がAPI名になります。カスタムオブジェクトにカスタムで定義したので、実際には SharingReason__c
というAPI名です。はい、これで事前準備はおしまいです。
Apex を書く
最低限のコードで書きます。恥ずかしい。クラスかもしてないので開発者コンソールからダイレクトにいけます。試すには十分です。
SharingObject__Share objShr = new SharingObject__Share();
objShr.ParentId = <対象のレコードID>;
objShr.UserOrGroupId = <共有したいグループ・ロール、またはユーザのID>;
objShr.AccessLevel = 'Read'; // None, Read, Edit, All
objShr.RowCause = Schema.SharingObject__Share.RowCause.SharingReason__c; // 作成した「共有の理由」
insert objShr;
このコードを実行すると、このように「共有理由」という理由になっています。独自の理由になっていることが分かりますね。
この状態で、所有者変更を行ってみましょう。はい、ご想像の通り共有設定が残ったまま所有者が変更できました。やったね(๑•̀ㅂ•́)و✧
追記
確定ではありませんが、Spring '21 Release Notes(preview) によると、Lightning でも「共有の直接設定」できるようになりそうですね、嬉しいです(´∀`*)ポッ