Tuesday, June 30, 2015

Salesforce Change Set Accelerators

Okay, so this post isn't really about web accelerators in the purest sense of the definition. But if you're frustrated with the experience of navigating and managing change sets in the UI, here are a few quick bookmarklets you can add to your browser to ease the pain.

To "install" a bookmarklet, simply drag the bookmarklet on to your browser's bookmarks bar. Or, in Internet Explorer, right-click the bookmarklet and click Add to favorites...

Last Tested Date: June 30, 2015 (Summer '15)

Change Set: Next


CS > Next

Ever notice that sometimes when you click Next to scroll through the pages of 25 components in a change set, the size of the table shifts and displaces the Next link? This simple bookmarklet clicks the Next link for you, without you having to move your mouse cursor.

Change Set: Previous


CS > Previous

Same as the Change Set: Next bookmarklet, but for the Previous link.

Add to Change Set: more (10,000 records per list page)


AtCS > more (10,000)

When adding components to a change set, especially for something like Custom Fields, you may have noticed two frustrating problems. First, clicking through multiple pages to find the record you want is a pain. Second, multiplying the pain is the fact that what you select on one page is lost when you switch to a different page. This bookmarklet sort of solves the problem by upping the size of the list to 10,000 records, which usually is enough to allow you to select and add all components of the same type at once.

Other tips


If you're planning to create a large change set as you build out your solution over multiple days or weeks, bookmarking the change set's detail page in your sandbox org should be a quick win.

Sunday, May 31, 2015

Why Roll-Up Summary Requires Master-Detail

There's an idea that is 7 years old on the Success Community titled, "Eliminate Need for Master-Detail Relationship for Roll-ups", and users have voted the idea up to over 25,000 points.


I won't lie. I am most likely one of the 2,500 users who voted in favor of the idea, who thought I can't believe a no-brainer like this is still an idea and not a GA feature!

But today, while watching Who Sees What: Record Access Via Sharing Rules I suddenly realized that the reason for the delay could actually be ridiculously simple: Implementing this feature would violate the security design of the Salesforce1 Platform. How? By exposing information that would otherwise be hidden when OWD is set to "Private".

Scenario: VIP bank accounts


Let's say you're a system administrator for a fictitious financial institution called SaaS Bank. At SaaS Bank, there are everyday customers, and then there are VIP customers. VIP customers at SaaS Bank are high-profile individuals of great importance or great wealth, and a few notable VIPs include Barack Obama, Warren Buffett and Marc Benioff.

Understandably, VIPs get the white glove treatment. Their relationships are discretely managed by handful of bankers in the Private Bank department within SaaS Bank. These bankers are known as Private Bankers, and their number one priority is protecting their client's sensitive data, namely the clients' bank accounts and balances.

Data on customers' bank accounts are stored in a custom object labeled Bank Account, and all bank accounts serviced by SaaS Bank are tracked in this object.

The security requirement: Everyone at SaaS Bank should be able to see that a VIP is indeed a customer, but only Private Bankers (and their trusted colleagues) should be able to see the bank accounts held by a VIP.

The simple solution would be to make the Bank Account custom object private using OWD. And to relate Bank Account records back to a customer (i.e., a standard Account record), the object has a Lookup(Account) field, not a Master-Detail(Account) field.

The tricky requirement: All users want to see aggregate balance data for their customers.

So, if you could create a Roll-Up Summary field on the Account object that sums all balances for a customer, you would violate the private sharing model for the Bank Account object. A Roll-Up Summary field holds a value that is calculated based on all pertinent records.

In a private sharing model, how would... how could the Roll-Up Summary field hold a value that simultaneously shows 0 to a regular banker, the total balance to a Private Banker and something in between to other bankers with whom a Private Banker has manually shared records? The answer is it can't.

Objects with Master-Detail fields inherit the record access controls on parent objects. In this case you can present aggregate information on parent records via Roll-Up Summary fields, because if you have access to the parent record you also have access to all child records. But when you use a Lookup field instead because you need different record access for child records, well...

Okay, I get it, and I still need a workaround


I think there are legitimate reasons why an organization would want aggregate data to be automatically calculated and displayed through a Lookup relationship. There are two ways to work around this:
  • Ignore the built-in security constraint and leverage Apex running in system context to perform the roll-up. You can even use an off-the-shelf solution the free Declarative Lookup Rollup Summaries app or the paid Rollup Helper app.
  • Use a custom visual element (e.g., Visualforce page) to display a contextual roll-up, taking into account the current user's access to child records. This would leverage the with sharing keyword to accurately display different values to different users.

In the end, it would be nice of either of the above options were made into native features. And I'm guessing that the first option, the convenient and intentional deviation from an established security model, is what the 2,500 supporters of that 7-year-old idea want.

Who Sees What: Record Access Via Roles (Corrected)

I'm admittedly a bit disappointed in the Who Sees What: Record Access Via Roles video. When I first read about the Who Sees What series, I thought it was awesome that salesforce.com decided to produce visual aids on the topic of security. As an alternative to the Security Implementation Guide, which boasts over 100 pages of official documentation on Salesforce security, I expected the videos to demystify the flexible and nuanced security controls available to system administrators.

However, after watching the Record Access Via Roles video, I feel that almost 70% of the content within is either misleading or simply inaccurate.

Note: I spent significant time staging test cases in an org before deciding to write this blog post, so please let me know if any part of my writing is technically wrong.

2:10 Three ways to open up access? Not quite...


In the AW Computing scenario, the presenter says that access to private Opportunity records can be opened up in one of three ways, quoted below:
  • "No access. In essence, this maintains the org-wide default of private. Users in this role would not be able to see opportunities that they do not own."
  • "View only. Users in a role can view opportunities regardless of ownership."
  • "View and edit. Users in a role can view and edit opportunities regardless of ownership."

This sounds good in concept, but as the video progresses to the demo portion to show how the three ways are actually implemented, the problem becomes clear. The presenter is actually misconstruing and wrongly explaining the Opportunity Access options.

In reality, the implicit access granted through the role hierarchy automatically solves the requirement presented in the video, and the Opportunity Access options are completely irrelevant to the hypothetical situation.

A more accurate explanation


Let's assume that the role hierarchy is set up as implied by the visual at 1:40 in the video.



Alan can see and edit whatever opportunities Karen and Phil can see and edit. The two reasons are that Alan is above Karen and Phil in the role hierarchy, and that OWD for the Opportunity object is configured to grant access using hierarchies (which as of Spring '15 you still cannot disable for standard objects). There are no more granular controls for records owned within a subordinate chain. If Karen can see a record, Alan can see that record. If Karen can edit a record, Alan can edit that record. Access via subordinates in the hierarchy is that simple.

So what do the Opportunity Access options do? Simply put, the options do exactly what the Role Edit page says they do.


Opportunity Access options have nothing to do with roles and subordinates. The selected option comes into play in situations, such as ones involving account teams, where a user from one branch in the role hiearchy owns an account, but a user from a different branch owns an opportunity for that account.

Try it yourself


Admittedly this will be really difficult if you don't have access to a sandbox org or a Partner Enterprise Edition org, but here's the idea.

Your role hierarchy looks something like the following:
  • CEO
    • SVP Products
      • Product Sales Manager
    • SVP Services
      • Services Sales Manager

Configure Opportunity Access for all roles in the hierarchy so that "users in this role cannot access opportunities that they do not own that are associated with accounts that they do own."

Set OWD for Opportunity to "Private", then do the following:
  1. Log in as a Product Sales Manager
  2. Create an account
  3. Create an opportunity
  4. Log in as a Services Sales Manager
  5. Verify that you cannot see the opportunity
  6. Create a new opportunity on the account owned by the Product Sales Manager
  7. Log in as the Product Sales Manager
  8. Verify that you cannot see the new opportunity created by the Services Sales Manager
  9. Log in as the administrator
  10. Change the Opportunity Access for the Product Sales Manager role so that "users in this role can view all opportunities associated with accounts that they own, regardless of who owns the opportunities."
  11. Log in as the Product Sales Manager
  12. Verify that you can now see the new opportunity created by the Services Sales Manager
  13. Verify that you you cannot edit that opportunity

Saturday, May 30, 2015

The Apex Ten Commandments (in Writing)

For anyone (like me) who couldn't find the slides to The Apex Ten Commandments recording referenced on the Architect Core Resources page, here's the written list:

  1. Thou shalt not put queries in for loops
  2. Thou shalt not put DML in for loops
  3. Thou shalt have a happy balance between clicks & code
  4. Thou shalt only put one trigger per object
  5. Thou shalt not put code in triggers other than calling methods and managing execution order
  6. Thou shalt utilize maps for queries wherever possible
  7. Thou shalt make use of relationships to reduce queries wherever possible
  8. Thou shalt aim for 100% test coverage
  9. Thou shalt write meaningful and useful tests
  10. Thou shalt limit future calls and use asynchronous code where possible

And I just have a couple of comments to add for color.

Comments on #7


I haven't tested this hypothesis yet, but... does this commandment still hold with large data volumes? Especially in the context of batch Apex? One certainty is that executing a single query like this is convenient for the developer. But when the query would return thousands of records that reference a small set of parent records, perhaps at larger data volumes a more efficient approach would be to split the query and leverage commandment #6 instead.

Comments on #10


The future annotation is slowly become obsolete with the introduction of the Queuable interface in Winter '15, although general guidelines for designing asynchronous automation still hold true.

Salesforce SSO in 5 Bullets

For my own edification, I want to summarize single sign-on options with Salesforce as succinctly as possible.

Using non-Salesforce credentials to get into Salesforce


This scenario can be simplified like this: A user already has a username + password combination stored in another system. The user wants to log into Salesforce using that existing username and password, instead of maintaining a separate username and password that's used only to log into Salesforce.

To achieve this, Salesforce allows:

Using Salesforce credentials to get into another app


This scenario can be simplified like this: A user is already logged into Salesforce. The user wants to launch another app without having to authenticate again. Instead, the other app should recognize the user and respond accordingly, based on the the user's Salesforce session.

To facilitate this, Salesforce offers:

Closing thoughts


A company can mix the two approaches above, so that Salesforce becomes an intermediate link in a chain that allows access to a third-party app using credentials maintained in a non-Salesforce system.

Thursday, May 28, 2015

3 Integration Practices Missing from White Paper

I just skimmed through the Integration Patterns and Practices white paper, which seems like a great primer on some time-tested integration approaches. However, two GA features plus a pseudo-integration option seem to be notably absent from the document.


Am I forgetting any other options? Please let me know!

Force.com Canvas


This is a well documented feature for which I'll summarize the key capabilities as of Summer '15:
  • Authentication via signed request or OAuth 2.0
  • Canvas app in Visualforce via apex:canvasApp component
  • Canvas app in the Publisher as a custom action
  • Canvas app in the Chatter feed as feed items
  • Canvas in the Salesforce1 app via the navigation menu

Lightning Connect


Instead of feeding data back and forth with integration jobs or real-time callouts, Lightning Connect offers a speedy alternative for surfacing external data in Salesforce, using the OData protocol. Simple scenario: Data stored in an on-premise database table can be exposed with a few clicks as an object in Salesforce, that looks and feels to end users like any other standard or custom Salesforce object. No code required!

Furthermore, Summer '15 added some really cool features to Lightning Connect, such as a native Salesforce Connector and the ability to access government and health data backed by Socrata Open Data Portal™. But in my opinion Lightning Connect will become absolutely, ridiculously amazing once write capabilities (still in Pilot) become GA, along with support for Process Builder, validation rules and Apex triggers.

HYPERLINK function in a formula field


Why do I even bother mentioning this? I think simply that the cheapest, crudest means of "integrating" two systems should not be overlooked as an option. Time is money, and if an external system supports deep linking or can process redirects to specific records, using a formula field to dynamically present a clickable URL to a user can be a really quick win.

Monday, May 25, 2015

Force.com Query Optimizer FAQ (cont'd)

The webinar, Inside the Force.com Query Optimizer delivered in April, 2013 is still featured as a relevant resource on the Architect Core Resources page. While the webinar explains many key considerations for designing queries, many questions linger. Let's take a closer look at these open questions, and let me know if you have any of your own to add!

Why does query optimization affect me as an admin? I don't write code.


If I were a betting man, I would bet that under the hood, SOQL queries, reports, list views and related lists on detail pages all tap into the same query execution framework. So, if you manage page layouts, reports and/or list views, you should care about the Force.com Query Optimizer.

What is a selective query?


A selective query is a query that leverages indexes in filters to avoid full table scans and to reduce the number of records in your result set below the selectivity threshold.

Stupid question, but what is an index?


This is a great question. Simply put, an index is a field-based mechanism by which a query can execute significantly faster, compared to execution without the index. Salesforce technical architects don't need to know how an index actually works behind the scenes, much like office workers don't need to know how a Keurig machine makes coffee at the press of a button.

A technical architect probably just needs to know that fields are either indexed or not indexed, and that indexed fields should be used in query filters. The technical architect should probably also know off-hand what standard indexes are available, and that custom indexes have lower selectivity thresholds and can only be created by Salesforce Support.

Anyone hardcore enough to dig into the Oracle database-level index machinery may want to check out the Database Systems course, offered gratis through MIT OpenCourseWare.

What's considered a standard index?


Great question! I wasn't able to find concrete documentation on this question, so you tell me (on Twitter)! I think an official answer would be a welcome addition to the "Force.com Query Optimizer FAQ" article. In the meantime, the list of indexed standard fields can be considered to all be standard indexes.

What is the selectivity threshold? And why should I care?


The selectivity threshold is the maximum number of records that can be returned in a result set, without disqualifying the index-based optimization option for a query. See the Query & Search Optimization Cheat Sheet for the exact calculations used with standard indexes and custom indexes.

Is there a difference between using nested queries vs. separate queries?


This was the first question asked on the Inside the Force.com Query Optimizer webinar during Q&A, "Is using nested queries good practice?" But I don't think the answer fully addressed the question. My personal guess (which needs to be validated in an org that actually contains large data volumes) is that nested queries have negligible impact on the execution time of a query, as long as the queries are not constructed in a way that uses the NOT operator.

The basis for my conjecture is a best guess that nested queries are executed sequentially, following an order of operations that allows the result set from one query to be used in another query. How true is this? I suppose I'll need to test all of the following query structures with selective filters applied:
More importantly, however, it's worth noting that in some instances executing separate queries in Apex is unfeasible, and the only viable alternative is to use nested queries. I could be wrong (and please correct me if I am), but one such situation could be an Apex method that needs to iterate through a result set using a for loop, processing child records for each record returned.