1

我正在尝试编写一个触发器,该触发器将使用来自子对象上的 RTA 字段的图像更新父对象上的 RTA 字段。

创建子对象时出现以下错误

Apex 触发器 Updateparent 导致意外异常,请联系您的管理员: Updateparent: 执行 AfterInsert 导致:System.StringException: Invalid id: (.....IMAGE IS DISPLAYED HERE....)外部入口点。

信息

Man Utd 是子对象 Account 是父对象 Image__c 是子对象上的 RTA 字段 Copy_image__c 是 accounts 上的 RTA 字段

这是触发代码

trigger Updateparent on Man_Utd_1__c (after insert, after update) {

    Map<ID, Account> parentAccounts = new Map<ID, Account>();

    List<Id> listIds = new List<Id>();

    for (Man_Utd_1__c childObj : Trigger.new) {
        listIds.add(childObj.Image__c);
    }

    parentAccounts = new Map<Id, Account>([SELECT id, (SELECT ID, Image__c FROM Man_Utd_s__r) FROM Account WHERE ID IN :listIds]);

    for (Man_Utd_1__c manu : Trigger.new) {
        Account myParentAccounts = parentAccounts.get(manu.Image__c);
        myParentAccounts.Copy_image__c = manu.Image__c;
    }

    update parentAccounts.values();
}

任何人都可以建议如何纠正这个问题,或者甚至可以这样做吗?

4

3 回答 3

0

编辑回答评论

这个对我有用,对空检查有一些细微的修改。搏一搏?该字段Image__c在客户和联系人上都被调用。

trigger rollupImage on Contact (after insert, after update) {

    Set<Account> parents = new Set<Account>();
    for (Contact child : trigger.new) {
        if(child.AccountId != null && child.Image__c != null){
            parents.add(new Account(Id = child.AccountId, Image__c = child.Image__c));
        }
    }

    if(!parents.isEmpty()){
        List<Account> toUpdate = new List<Account>();
        toUpdate.addAll(parents);
        update toUpdate;
    }
}

原来的

错误

都写在那里了;)

List<Id> listIds = new List<Id>();

for (Man_Utd_1__c childObj : Trigger.new) {
    listIds.add(childObj.Image__c);    // boom happens here?
}

您正在将富文本区域值(其中包含编码图像的非常长的字符串)分配给 Id 变量(15 或 18 个字符的特殊字符串)

试试这样:

Set<Id> ids = new Set<Id>(); // Set will ensure we won't have duplicate values
for (Man_Utd_1__c childObj : Trigger.new) {
    ids.add(childObj.Account__c);
}

优化 - 第一轮

在第二个循环中,您正在设置Copy_Image__c字段,但在 Account 的本地副本(循环范围内的局部变量)上。我不确定将其设置在那里是否会将更改传播到父 acc(它可能是完整副本,而不是对地图中项目的引用。您可以将其放回(parentAccounts.put(manu.Account__c, myParentAccounts))到地图或只是进行图像分配直接地:

parentAccounts = new Map<Id, Account>([SELECT id FROM Account WHERE ID IN :ids]);
// I've removed the subquery, you don't need it, right?

for (Man_Utd_1__c manu : Trigger.new) {
    if(parentAccounts.containsKey(manu.Account__c)){
        parentAccounts.get(manu.Account__c).Copy_image__c = manu.Image__c;
    }
}
update parentAccounts.values();

优化 - 第 2 轮

看起来有点愚蠢——我们查询 Accounts 但我们需要获取的只是 ID...但我们已经知道 ID,对吗?所以 - 看看这个“专业技巧”(分享只是因为我的同事是曼联的忠实粉丝;))

trigger Updateparent on Man_Utd_1__c (after insert, after update) {

    Set<Account> parents = new Set<Account>();
    for (Man_Utd_1__c child : trigger.new) {
        if(child.Account__c != null){
            parents.add(new Account(Id = child.Account__c, Copy_Image__c = child.Image__c));
        }
    }

    if(!parents.isEmpty()){
        List<Account> toUpdate = new List<Account>();
        toUpdate.addAll(parents);
        update toUpdate;
    }
}
于 2014-01-21T18:58:49.913 回答
0

注意:优化是编写触发器时的关键。

在编写触发器时,请确保您遵循所有最佳实践:

触发主题演讲:

  • 优化 - 我已经在大写和第一行中指定了它,因为它是编写逻辑时的关键
  • 适当的缩进和代码注释,这样任何处理相同代码的人只要看一下注释就可以很容易地理解逻辑。确保在初始评论中更新 lastModifiedBy 行,以便跟踪谁最后工作/最后更新以及在什么日期工作。最好在每一行上保留正确的代码注释 - 仅在需要时
  • 具有专有名称的变量例如:如果 var 是列表类型,则为“lst”前缀或“列表”后缀,然后是专有名称例如:lstContactsToInsert 或 lstContactsToUpdate
  • 始终创建一个单独的处理程序类,并且不要在触发器本身上编写所有逻辑“作为最佳实践遵循”
  • 有适当的触发上下文。通过触发器上的销售人员文档了解何时使用正确的触发器上下文。如果可以使用此处理,则使用“之前”上下文,如果不能,则使用“之后”上下文,以便限制 DML。

处理程序的主题演讲:

  • 触发器中提到的前 3 个步骤也适用于此处
  • 在编写逻辑的地方使用常见的私有方法并在其他方法中使用它

TestClass 的主题演讲:

  • 始终在测试类中使用“通用测试数据类”编写测试类。
  • 使用正确的测试方法名称,例如: test_Method_One 'OR' testImageUpdates
  • 使用断言并测试所有用例 - 否定和肯定测试

#1。扳机

   /**
    *   @TriggerName : ContactTrigger
    *   @CreatedBy   : Rajesh Kamath
    *   @CreatedOn   : 30-Nov, 2016
    *   @Description : Trigger to update the image on parent object 'Account' based on the child object 'Contact' 
    *   @LastModified: None
    */  
    trigger ContactTrigger on Contact(after insert, after update) {

        //Instantiate the handler class
        ContactTriggerHandler objContactHandler = new ContactTriggerHandler();

        /* Trigger Context */
        if(Trigger.isAfter) {

            //Fire on Insert
            if(Trigger.isInsert) {

                objContactHandler.onAfterInsert(trigger.new); 
            }

            //Fire on Update
            if(Trigger.isUpdate) {

                objContactHandler.onAfterUpdate(trigger.new, trigger.oldMap);
            }
        }
    }

#2。处理程序

   /**
     *   @HandlerName   : ContactTriggerHandler 
     *   @TriggerName   : ContactTrigger 
     *   @TestClassName : ContactTriggerHandlerTest [Make sure you create this with the steps at the end of this handler] 
     *   @CreatedBy   : Rajesh Kamath
     *   @CreatedOn   : 30-Nov, 2016
     *   @Description : Trigger to update the image on parent object 'Account' based on the child object 'Contact' 
     *   @LastModified: None
     */  
    public with sharing class ContactTriggerHandler {

        /*
           @MethodName : onAfterInsert
           @Parameters : List<Contact> lstNewContactRecords
           @LastModifiedBy : None [Make sure when anyone updates even this line will be updated for help for other users who work on later phase]
        */
        public void onAfterInsert(List<Contact> lstNewContactRecords){

            //Call a common method where we have logic
            reflectChildImageOnParent(lstNewContactRecords, null);      
        }

        /*
           @MethodName : onAfterUpdate
           @Parameters : List<Contact> lstContactRecords, Map<Id, Contact> mapOldContactRecords
           @LastModifiedBy : None [Make sure when anyone updates even this line will be updated for help for other users who work on later phase]
        */
        public void onAfterUpdate(List<Contact> lstContactRecords, Map<Id, Contact> mapOldContactRecords){

            //Call a common method where we have logic
            reflectChildImageOnParent(lstContactRecords, mapOldContactRecords);     
        }

        /*
           @MethodName : reflectChildImageOnParent
           @Parameters : List<Contact> lstContactRecords, Map<Id, Contact> mapOldContactRecords
           @LastModifiedBy : None [Make sure when anyone updates even this line will be updated for help for other users who work on later phase]
        */
        private static void reflectChildImageOnParent(List<Contact> lstContactRecords, Map<Id, Contact> mapOldContactRecords){

            /* Local variable declaration */
            List<Account> lstAccountsToUpdate = new List<Account>();

            for(Contact objContact : lstContactRecords) {

                //Execute on insert and update
                if((Trigger.isInsert || (Trigger.isUpdate && objContact.Child_Image__c != mapOldContactRecords.get(objContact.Id).Child_Image__c)) && objContact.Account__c != null) {

                    //List of accounts to update
                    lstAccountsToUpdate.add(new Account(Id = objContact.Account__c, Parent_Image__c = objContact.Child_Image__c));                  
                }
            }

            //Update the account records
            if(!lstAccountsToUpdate.isEmpty()) {

                update lstAccountsToUpdate;
            }
        }
    }

这可以参考您的用例。 如果这有帮助,请标记为“最佳答案”

于 2016-11-30T07:13:02.217 回答
-1

忠诚度 - 子对象

领域:

  1. lightingdata__Contact__c(关系)
  2. lightingdata__imagenims__c// 图像字段

联系 - 父对象

场地:lightingdata__Imagefromloyalty__c

trigger loyaltytocon on Loyalty__c (after insert, after update) {
    Map<id, Contact> conlist;
        List<Id> idlist=new List<id>();
        for (Loyalty__c loy:trigger.new) {    
            idlist.add(loy.lightingdata__Contact__c);
        }
        conlist= new Map<id, contact>([select id, lightingdata__Imagefromloyalty__c from contact where id In : idlist]);

        for(Loyalty__c lo:trigger.new){
            contact con = conlist.get(lo.lightingdata__Contact__c) ;
            system.debug('con data' + con);
            con.lightingdata__Imagefromloyalty__c = lo.lightingdata__imagenims__c;
        }
     update  conlist.values();
}

在父对象字段中,它将返回具有 URL 的图像文件。然后您可以创建一个公式文件,只需lightingdata__Imagefromloyalty__c在公式中引用 ( ) 即可显示图像。

于 2017-04-27T12:38:39.780 回答