Cross-Object Owner Formulas

There is a little new feature that is set to arrive in the Summer 13 release that garners only half a page of the release notes, but creates an extremely important opportunity for projects wanting to maximize their time and resources by leveraging clicks before code.

In the past, Owner was a troublesome relationship field. Most relationship fields support cross-object formula references to access related parent data, but until the Summer 13 release, this has not been the case with Owner. Almost every sObject has this field, and in many, Owner can only be a user. But in Lead, Case, and custom sObjects, Owner is either a user or a queue. This means at the data model level, the field is polymorphic and can contain either a user or a group id value.

Owner as a polymorphic relationship

I always suspected this was part of the reason why this relationship field did not support cross-object formulas. With a polymorphic relationship, how do you resolve the difference in fields between the several types of parent objects? Consider this theoretical (but invalid) cross object reference:

Owner.LastName

That’s all well and good if the Owner value is related to a user. The User sObject has a field called LastName. But if Owner is related to a queue, my formula could potentially create a runtime error for the lack of LastName field in the Group sObject.

There were workarounds. Most commonly, in an sObject like Account, where Owner can only be a user, it would be to use a trigger to populate a secondary lookup relationships field with the user ID on save. Ugh!

With the advent of the cross-object owner formula feature, there is now native support for using cross-object formulas for all Owner fields. Because of the polymorphic nature of Owner, there’s a slightly different notation from other cross-object formula references you might have used in the past, but it is an easy adjustment.

Owner:[User|Queue].FieldName

What about a formula field that displays the Owner’s Manager’s name?

Owner:User.Manager.FirstName & ' ' & Owner:User.Manager.LastName

Or a validation rule that requires that certain status values are not allowed when the record is in a queue? We can detect the presence of either the User or Group parent type by checking to see if the Id field is blank for that type.

ISBLANK(Owner:User.Id) && ISPICKVAL(Status__c, 'In Process')

Of course, you can also use references to the Group sObject that represents the queue, but there is limited need for this owing to the lack of meaningful data held in Group. For the purposes of queues, there is the name, the email address, and that is about it. But if you did want to get a reference to the group email address, for instance, you can still do that. In the release notes there is this example formula:

Ostensibly this example would be a formula field showing either the Queue or User email address, depending on which is assigned currently.

As a programmer, I enjoy solving a problem with code. That’s why Apex exists. But coding workarounds isn’t fun and the workaround for this in code was ugly and uninteresting. Not the kind of task I look forward to as a developer.

As I implied at the beginning of this blog, in reading the release notes, you might infer that this is a small new feature. But for me it is almost as important as the addition of criteria-based sharing rules in the Spring 11 release a couple of years ago. Proper application of the declarative framework including formulas and rules can save a project hundreds of lines of code and days of work. With this addition to the platform, it further refines these tools in the toolkit for implementers.

I’m a huge fan of the Force.com platform, and in addition to teaching I’ve had the chance to work on a few pro-bono projects for our Salesforce Foundation customers as part of Salesforce.com’s 1/1/1 Philanthropic Program.

Having just devoted the past 3 years of my life almost exclusively to Force.com I’m very excited at how this new job will be taking me into new and exciting technologies that integrate and work with the platform. You can follow me on Twitter on @pchittum where I post about work topics.

Update:

I was having so much fun playing with this feature with Lead, Case, and Custom sObjects, I didn’t really play around with this for standard objects where User is the only type of owner (Account, Opportunity, etc.). In this instance, the owner type is not needed in the notation. So for the example above, showing the owner’s manager’s name. If I were to do that on an Account, I would simply use the syntax:

Owner.Manager.FirstName & ' ' & Owner.Manager.LastName

The good news is the error message was self-explanatory when I tried to use the object type. It told me, “You don’t need to specify an object type for the Owner field. Remove User from your formula.”

It was also brought to my attention by product management that owner can be a Calendar where the sObject is Activity. I confess I was not aware of this having never worked on customizing the Activity object. In Activity the Owner field is labeled Assigned To. So in addition to the syntax notation for most objects, for activity, you will also have: