【问题标题】:How to create an Apex Class?如何创建 Apex 类?
【发布时间】:2018-10-10 06:12:33
【问题描述】:

通过大量试验和错误,我在我的沙盒中创建了功能触发器。我的问题是我现在想将它应用到我的 live org,但我似乎无法理解整个 apex 类的东西。

如何创建课程?

我的触发器背后的想法是,当保存机会记录时,soql 查询将查看在类别字段中选择的选项列表值,并找到具有匹配名称的活动供应商或成员服务帐户类型,并将其带入销售人员 ID。将该 sfid 放入我的供应商名称查找字段将使我能够在机会和供应商/成员服务帐户之间建立其他工作流规则和字段更新所需的关系。

    trigger Find_Vendor on Opportunity (before insert)
    {
       for(Opportunity u:trigger.new)
       {
          if(u.Vendor_Name__c == null)
          {
              u.Vendor_Name__c =   [Select Id From Account
                             Where (Account_Type__c = 'Vendor'
                             OR Account_Type__c = 'Member Services')
                             AND Status__c = 'Active'
                             AND Name = :u.Category__c limit 1].Id;
          }
       }
    }

【问题讨论】:

  • 那么您的触发器是否按预期工作?我是否理解你现在想把它从你的测试组织放到你的实时组织?
  • @utm 没错。只是想把它从测试组织带到现场组织。
  • 所以关键是你不能直接在 Live-Org 中部署一些东西。您必须使用变更集。为此,您的 test-org 必须与您的 live-org 连接。如果这样做了,您可以在测试组织中创建包含所有更改(类等)的出站变更集。必须上传此变更集,然后在其他组织(实时组织)上导入此变更集(入站变更集)。我建议阅读/执行“使用更改集从沙盒部署”Trailhead 教程

标签: triggers salesforce apex test-class


【解决方案1】:

我不会将此触发器部署到生产中,它有很多问题并且可能会中断,因为您在 for 循环中执行 SOQL 查询,而且逻辑似乎没有经过深思熟虑。看到您似乎不太擅长编写触发器,您可能应该查看一个声明性解决方案,例如process builderheadless flow,您可以在其中获得相同的结果。如果您坚持使用触发器,我建议您使用以下内容:

 trigger Find_Vendor on Opportunity (before insert)
{
   Set<String> categories = new Set<String>();
   Map<String, Id> categoryAccountIdMap = new Map<String, Id>();
   for(Opportunity u:trigger.new)
   {
      if(u.Category__c != null)
      {
           categories.add(u.Category__c);
      }
   }
   List<Account> categoryAccounts = [Select Id From Account
                         Where (Account_Type__c = 'Vendor'
                         OR Account_Type__c = 'Member Services')
                         AND Status__c = 'Active'
                         AND Name IN :categories];
   for(Account acct : categoryAccounts){
       if(!categoryAccountIdMap.containsKey(acct.Name)){
            categoryAccountIdMap.put(acct.name, acct.Id);
       }
   }
   for(Opportunity u:trigger.new)
   {
      if(u.Vendor_Name__c == null && categoryAccountIdMap.containsKey(u.Category__c))
      {
          u.Vendor_Name__c =   categoryAccountIdMap.get(u.Category__c);
      }
   }
}

您还需要对触发器进行一些测试覆盖才能释放,但只需在测试中插入一个机会就足够了

@IsTest
private class SomeTestClassName {

@isTest
static void testOppVendor() {
 //you may need to add required fields to these objects to actually insert  them
    Account a = new Account(Name = 'Category 1');
    insert  a;
    Opportunity o = new Opportunity(Name = 'test', StageName = 'Closed Won', Category__c = 'Category 1');
    insert o;
    o = [SELECT Vendor_Name__c FROM Opportunity where Id = :o.Id];
    System.assertEquals(a.Id, o.Vendor_Name__c);
}

话虽如此,这里没有使用许多最佳实践,例如测试数据工厂和将业务逻辑从触发器转移到您绝对应该熟悉的领域类。

【讨论】:

    【解决方案2】:

    在建议您将其部署到 live org 之前,我想指出您的代码存在的一些问题。

    1. 您正在 for 循环中使用 SOQL 语句。在 SF 环境中,每个事务限制为 101 个 SOQL 查询。当您对您的 OPP 进行大规模更新并且其中超过 101 个时,您将遇到 SOQL LIMIT:太多查询。 description here

    2. 为了能够部署到生产组织,您需要有测试覆盖率。因此,为了能够将此触发器部署到生产环境,您需要创建一个测试。 basic resources here。不要忘记运行一些批量测试。

    3. 我建议您不要使用触发器来实际执行功能。您最终将在您的组织中获得大量触发器,并且您将很难管理它们何时执行的顺序。尝试采用触发器不包含任何逻辑的模型,除非它是在更新之前或之后等等。基本解释可见here

    sfdc99.com 是了解更多关于 SF 限制和最佳实践的重要资源。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-13
      • 1970-01-01
      • 2022-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多