0

what i am trying to do is make a trigger on contact in which field acc_number__c is updated in Contact from the account field acc_number__c if the checkbox field final_number__c is selected in the contact object. after reading about after and before triggers, what i came to understand is to use before if i only need to validate the field values that user inserts and when fields that are from the trigger object needs to be updated. and to use after when i need to insert or update fields for other object.

So based on that i choose before , but ultimately did on both, the problem is it is working on the after trigger but i can't seem to think the right logic for before trigger.

    trigger Accnumberupdate3 on contact (before insert ,before update) {


            list<account> con = new list<account>();
             Set <id> ids = new set<id>();

              for( contact c : trigger.new){
              if(c.Finalize_Number__c == true){
               ids.add(c.accountId);}
       } 
           con = [select acc_number__c,id from account where id in :ids];

            contact c = new contact();
            for(account acc : con){

            if(c.Finalize_Number__c == true){

                c.Acc_Number__c = acc.acc_number__c;

                    }

             }




}

no error is shown but the field does not get updated

the after trigger for this works though

trigger Accnumberupdate2 on contact (after insert ) {

            list<contact> conlist = new list<contact>();
            list<contact> con = new list<contact>();
           Set <id> ids = new set<id>();
       for(contact c : trigger.new){
              if(c.Finalize_Number__c == true){
                system.debug('If condition');
                ids.add(c.Id);
                              }
       }
            con = [select acc_number__c,finalize_number__c,account.acc_number__c from contact where id 
                    in :ids];


        for(contact c : con){

                c.Acc_Number__c = c.account.acc_number__c;
                conlist.add(c);


             }


 update conlist;   

}

What am i doing wrong, also spare me please if I did a silly mistake, i am just 2 weeks old into this.

Thank you, Nitin

1
  • 2
    As a tip you don't need to compare boolean variables on if statements you can directly type if(c.Finalize_Number__c) to evaluate them by its value. It will save you space and improve readability of your code. May 22, 2017 at 9:53

2 Answers 2

0

You can achieve the same Using the Formula.Just make acc_number__c as formula field and use the below formula

IF(finalize_number__c, Contact.Account.acc_number__c ,''  )

In your code you are writing a SOQL and getting the records in list con.You are then forming the updates on this list which in not in trigger.new context.You need to loop through the trigger.new again and then updates the records if you don't want to write a DML.

Another answer by D_k should resolve your issue.

Try this

trigger Accnumberupdate3 on contact (before insert ,before update) {
            Set <id> ids = new set<id>();

              for( contact c : trigger.new){
                  if(c.Finalize_Number__c == true){
                   ids.add(c.accountId);
                }
       } 
      Map<Id, Account> mapAcc = new Map<Id, Account>(
    [SELECT id,name from Account where id in :ids]
);

        for (Contact con : trigger.new) {

            if (con.Finalize_Number__c == true) {
                if (mapAcc.containsKey(con.AccountId)) {
                    con.Acc_Number__c = mapAcc.get(con.AccountId).acc_number__c;
                }
            }

        }    

}
0
-1

Everything is fine in your trigger except for:

1.You are instantiating a new contact and assigning it the acc_number__c value when you do this you are just creating a contact in the memory.

Contact c = new Contact();
  1. You are looping over accounts (You actually need to loop over the trigger.new list and update it) and assigning the acc_number__c without even checking for a related contact record (This could be easily done using a Map. see point 3).

for (account acc : con) { if (c.Finalize_Number__c == true) { c.Acc_Number__c = acc.acc_number__c; } }

  1. The result from query should be filled in Map<Id, Account>, so that it's easy to identify a Contact's association to an account (via AccountID, please refer to the below code).

Try This:

trigger Accnumberupdate3 on contact (before insert , before update) {

    Set <Id> ids = new set<Id>();

    for ( contact c : trigger.new) {
        if (c.Finalize_Number__c) {
            ids.add(c.accountId);
        }
    }

    Map<Id, Account> mapAcc = new Map<Id, Account>(
        [SELECT acc_number__c, Id from Account where Id IN :ids]
    );

    for (Contact con : trigger.new) {
        if (con.Finalize_Number__c) {
            if (mapAcc.containsKey(con.AccountId)) {
                con.Acc_Number__c = mapAcc.get(con.AccountId).acc_number__c;
            }
        }
    }

}
1
  • 1
    Code dumps without explanation aren't very useful as answers. Just giving someone the answer doesn't help them learn anything (and I am glad to see that Niknit is interested in learning the reason why things work rather than just taking this and copy/pasting). I've downvoted this answer for now, but if you edit your answer to include an explanation of how this works and how it's different from the code provided by Niknit, I'll retract my downvote.
    – Derek F
    May 22, 2017 at 14:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .