As usual, the inspiration for this post comes from a question on the Salesforce Answers Community that I recently came across:
Giving a user access to 1 record on an object
I suggested using Apex Managed sharing to Sam but with the known power of Process Builder and Flows, I wanted to explore if this capable combo can accomplish what is needed without the use of Apex. And guess what? I wasn’t disappointed and was able to get it working without a single line of code. So the following approach which earlier needed Apex can be easily handled via point and click tools like Process Builder and Flows:
Using Apex Managed Sharing to Create Custom Record Sharing Logic
Data Model and Sharing: Wayne Enterprises has built a Recruitment application within Salesforce that is used to track candidates and their job application progress. Candidate custom object is used to store Candidate information and Reviews custom object is used to store the Reviews associated with the Candidate. Reviews object is the child of Candidate object and is related via a Lookup relationship (One Candidate can have multiple Reviews). Both Candidate and Review objects have the Organization Wide Defaults set to Private. Hiring Manager is a lookup field on the Candidate object that allows the HR to select a user as the Hiring Manager.
Business Requirement: Whenever the Hiring Manager lookup field is populated on the Candidate record, this record and all related Reviews for the Candidate should become editable for the Hiring Manager. Since the OWD for Candidate and Review objects is Private, these records won’t be otherwise visible to non-record owners hence custom sharing needs to be implemented. For Wayne Enterprises, Camila Martinez is one of our Hiring Managers.
As you can see below, without the Hiring Manager field populated on the Candidate record, it is not available for Camila Martinez (Hiring Manager) to view and the same applies to related Review records.
Solution: Before we devise the solution, let’s be aware of a few considerations:
- Any object in Salesforce whose OWD is more restrictive than Public Read/Write i.e. it’s Private or Public Read Only will have a corresponding “Share” object. The API name for this object will be ObjectName_Share__c. For standard objects like Account and Contact, the corresponding Share objects are AccountShare and ContactShare.
- Anytime sharing is established on an object’s record , a record is inserted into this Share object. This would be the crux of our implementation. The supported sharing types are: Force.com managed sharing, user managed sharing and Apex managed sharing
- Every share object (For example: AccountShare, CandidateShare__c, ReviewShare__c) has the following properties:
- We will be utilizing Apex Managed Sharing but will implement it using Process Builder and Flows. Apex managed sharing must use an Apex sharing reason which is a way for users or developers to know why a certain record was shared with a user or a group of users. It’s also helpful for developers to troubleshoot sharing related issues.
- Apex sharing reasons will be defined on the object’s details page and each Apex sharing reason will have a label and a name. We will see all of this in action when we get down to implementation.
- Apex managed sharing is maintained across record owner changes.
Create Apex Sharing Reasons
Since we need the sharing across both Candidate and Review object records, we need to create the Sharing reason on both objects:
Create the Flow
Within the Flow, we will first create a CandidateShare__c record which provides Edit access to the Hiring Manager. We then do the same for all Review records related to the Candidate.
Now we could have avoided the Assignment steps below but why are we going through all of this effort? It’s because we want to Bulkify our Flow. As a Flow design best practice, always perform DML (Fast Create and Fast Update) outside of the Loop and never within the Loop.
Create the Process to launch the Flow
The Process will fire and launch the Flow whenever the Hiring Manager field is populated on the Candidate record. The Flow above will perform the heavy lifting of sharing the Candidate record and all related Review records with the Hiring Manager.
And that’s it. Don’t forget to activate the Process. It’s time to see the magic happen.
Here is the Candidate record after we populate it with with Camila Martinez as the Hiring Manager:
Now when Camila Martinez logs in and tries to access our candidate’s (Mark) record, she can successfully see the record as well all related Review records:
Wasn’t that simple? See how the CandidateShare__c and ReviewShare__c records were inserted via the Flow (you can check this by clicking the Sharing button on Candidate and Review records):
Please feel free to share any other point and click approach for implementing a similar scenario in the comments below. Until then, ciao!