Salesforce的Prefix和Suffix

行家一出手,就知有没有。
判断一个Salesforce从业者是不是老手的一个标准,
就是能不能对Governor Limit,Sobject的Prefix和Suffix倒背如流。

Governor Limit之前已经介绍过了,
Salesforce说了,当你觉得Governor Limit限制了你,那么意味着你的业务流程没有达到最优。

那么Prefix是什么呢。
Prefix就是俗称的3位码。
每个SObject都有一个3位编码,每一条该SObject的数据的头三位,都是以此3位编码开头。
如果把三位编码放在salesforce的url后面,可以快速的访问SObject的ListView页面。
https://[your instance name].salesforce.com/[prefix]

标准SObject的prefix都是固定的,
比如,Account一定是001
Contact一定是003
Lead一定是00Q
而自定义SObject就没有固定的编码了,但都以aXX开头。

Salesforce提供了一本速查手册
列出了所有标准SObject的prefix。
如果想得到一个全体SObject的花名册,可以去实现一下tooling api。
所有标准的,自定义的,还有不可见的SObject的Prefix都列出来了。

那么,Suffix呢,大家最熟悉的莫过于”__c”,
所有的自定义SObject的Suffix,所有自定义字段的Suffix,都是它。
那么除了__c之外,还有哪些呢。
国外大神总结在此
防丢失转载如下:

__c Custom Object or Custom field
__r Custom relationship field as used in a SOQL query to traverse the relationship
__ka KnowledgeArticle
__kav KnowledgeArticleVersion
__Feed Article Type Feed or Custom Object Feed
__ViewStat KnowledgeArticleViewStat
__VoteStat KnowledgeArticleVoteStat
__DataCategorySelection Article Type__DataCategorySelection
__x External Object
__xo Salesforce-to-Salesforce (S2S) spoke/proxy object
__mdt Custom Metadata Type
__Share Custom object sharing object
__Tag Salesforce Tags
__History Field History Tracking for Custom Objects
__pc Custom Person Account Field
__pr Used for traversing custom Person Account relationship fields
__hd Historical Data
__hqr, __hst Start/End of the Datetime range
__b BigObject
__latitude__s Geolocation Latitude Coordinate
__longitude__s Geolocation Longitude Coordinate
__e Platform Events – a.k.a. EventBus event (Winter ’17 pilot)
__p Custom Person Object (Spring ’15 pilot)

————By Daniel Ballinger

Salesforce的Field Id与URL Hack

默认值是个好东西。
别说是普通用户,就算是开发者,在面对满满一屏的空白字段时,也是要不禁皱皱眉头的。

设置得当的默认值可以极大的提高业务流畅度与用户满意度。
反之,每次都不得不改的默认值,会带来加倍的苦恼。(甚至会惹恼用户)

当然,Salesforce提供了字段的Default Value功能。
我们可以为大部分字段类型设置默认值。

Default Value必须为公式,并且不能使用其他字段的值,只可以使用预设的系统变量和环境变量。
因为这样的限制,使得我们在使用自定义button或者link跳转到Object标准编辑画面的时候,无法根据情况显示不同的默认值。

举个例子,比如Case上面有个字段用来储存Case的类型,然后在Case的详细画面上放置一个自定义Button,这个button用来新建一个order。
为了提高Agent的工作效率,弹出order的新建页面之后,我们希望order的类型是Case上所选择的值,并且与Case关联同一个Account。

这种场景下,字段的Default Value已经无法满足需求。
我们需要使用一种Salesforce并不提倡的技巧———-URL Hack。

URL Hack就是通过在Salesforce的URL上加上额外的参数,来实现我们的需求。
其中一种技巧,就是给Standard Pagelayout赋值。

那么让我们来看看URL Hack到底是什么样子。
首先,点击Case标签里的新建Button。
跳转到Case的新建画面之后,观察地址栏的URL如下
无RecordType: https://[InstanceName].salesforce.com/500/e?retURL=%2F500%2Fo
有RecordType: https://[InstanceName].salesforce.com/500/e?retURL=%2F500%2Fo&RecordType=0126F000000v348&ent=Case

其中,500代表Case,每个Object都有一组三位码,同时也意味着所有的数据的Id都是由这三位码开头。
e代表编辑页面。 500/e代表新建数据,500XXXXXXXXX/e代表修改既存数据。
retURL代表回调页面,当点击取消Button之后,会返回到指定的页面。在例子中,%2F代表“/”,所以会返回500/o。
有RecordType的URL多了一个RecordType参数,值0126F000000v348就是recordType的Id。

所以,RecordType以外的字段,我们也可以通过同样的方式进行赋值。

首先,与RecordType不同的是,我们需要用的并不是字段的API名,而是Field ID。
如果不使用工具的话,Field Id并没有快捷的查看方式,所以应急的话,可以直接打开编辑画面,然后用浏览器的F12开发者工具直接查看。

标准字段是字母+数字的形式,自定义字段则是以00N开头的ID。
就拿上面的例子来说,如果将“123456”赋给Account Number,URL应写为
https://[InstanceName].salesforce.com/500/e?acc5=123456&retURL=%2F500%2Fo

如果是Lookup字段的话,上面那样写就行不通了,要在Field Id后面加上_lkid后缀
标准字段的话,我们以Account的Parent Account为例
https://[InstanceName].salesforce.com/001/e?acc3_lkid=001XXXXXXXXX

自定义字段的话,Lookup字段还需要在00N前加上CF
https://[InstanceName].salesforce.com/001/e?CF00NXXXXXXXXX_lkid=001XXXXXXXXX

有的时候只写lkid结尾的参数看起来并不管用,在编辑页面上,Lookup字段仍然是空白的,但实际上保存之后是已经被赋值的。
如果遇到这种现象,就要加额外加一个参数
https://[InstanceName].salesforce.com/001/e?acc3_lkid=001XXXXXXXXX&acc3=RecordName
https://[InstanceName].salesforce.com/001/e?CF00NXXXXXXXXX_lkid=001XXXXXXXXX&CF00NXXXXXXXXXX=RecordName

最后记住,一定要养成随时设置retURL的好习惯。

上述所有的值在Custome Button或者Link中,都可以用表达式替换,比如
00NXXXXXXXXXXXX={!Case.Status}等。

如果想了解URL Hack还能做哪些事情,之后会写一篇专访。

Salesforce的TestClass

虽然Salesforce从业人员应该尽量使用标准功能来实现需求,
但仍不可避免的要用到代码。

标准功能的话,Salesforce会自己负责质量(虽然Bug频发。。。),
对于自定义功能,Salesforce则制定了质量标准,
比如,如果总体代码覆盖率不到75%,无法Deploy。

一般的Apex Code,就像那些出现在Trigger里,出现在Controller里的代码,
测试类都很好写,就按照
1. 准备测试数据
2. 执行业务逻辑
3. 断言执行结果
按套路打就行了。

除此之外,另一些apex code,需要特别的测法。
Salesforce作为CRM系统,无法避免的要与其他系统进行数据交互。
大部分情况,我们只需要把salesforce的标准集成文档和权限已经配置妥当的账号,提供给对方就好,
但是,当我们需要将业务封装起来的时候,就需要自己建WebService。
况且,Salesforce主动调用外部系统接口的时候,又要区分是Rest还是SOAP。

对于Apex Rest Callout可以使用下面三种方式(代码示例点击链接)
1. HttpCalloutMock
比较常见的写法,有极大的可拓展性(毕竟连响应结果都要自己Code进去)。
2. StaticResourceCalloutMock
LoadData是一对好兄弟,都是在Test Class中利用StaticResource,可以很好的做到测试数据与测试代码分离。
3. MultiStaticResourceCalloutMock
StaticResourceCalloutMock的复数URL版。

对于Apex SOAP Callout,Salesforce也提供了一种方式。
1. WebServiceMock

以上是Callout的测试类写法,原理均是构造一个Mock类,然后提供一个假的response。
你总不能期待每次跑测试类的时候,让人家集成方的服务器真的去响应你吧?

那么Callin呢。
首先,处理Callin的Apex Class一定是WebService。
WebService也分为Rest Webservice和SOAP WebService。
对于Rest WebService,Salesforce并没有提供类似与Mock类的工具类,所以我们直接去构造上下文环境。
在实际情况种,上下文环境是由系统进行构造的,这里我们代替系统。

        .................
        RestRequest request = new RestRequest();
        request.requestURI = 'https://[InstanceName].salesforce.com/services/apexrest/xxxxxx/';
        request.httpMethod = 'GET';
        RestContext.request = request;
        /** Call your WebService like below **/
        MyWebService.MyFoo();
        .................

对于SOAP Webservice就简单多了。因为不需要处理上下文环境的参数等内容,直接处理方法中的参数就好,
所以就当作普通的Apex Code处理就可以,不需要特殊的操作。

除此之外。

虽然目前我还没见有人用过,但是Salesforce还是提供了一个Stub接口,用来做Mock框架。
它的好处是可以实现单元测试的完全解耦,对各个小模块进行单独的测试。
就目前市面上各个大公司的状况来看。。。能好好写个断言就不错了。(捂脸)(尴尬)