Contact trigger to limit an account to not have more than 2 contacts





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







1















Yesterday I got rejected from a job interview because the interviewer asked me to write a trigger to limit the number of contacts per account and I wrote exactly the below but he said this won't work and it is not the correct way to write the same.
I ran the same and it is working fine I am not able to see any problem with the below code can someone please help me understand from the interview's perspective why he said this is not the right way.



    trigger ContactTrigger on Contact (after insert, before Insert, before update, after update) {

if(Trigger.operationType == triggerOperation.AFTER_INSERT || Trigger.operationType == triggerOperation.AFTER_UPDATE) {
set<Id> IdSet =new set<Id>();
for(Contact cot : trigger.new) {
if(cot.accountID != null) {
IdSet.add(cot.accountId);
}
}

Integer contactListCount = [Select count() from contact where accountID IN: IdSet];

if(contactListCount > 2) {
for(contact cop : trigger.new) {
cop.addError('cannot have more than 2 contacts per account');
}
}
}
}









share|improve this question































    1















    Yesterday I got rejected from a job interview because the interviewer asked me to write a trigger to limit the number of contacts per account and I wrote exactly the below but he said this won't work and it is not the correct way to write the same.
    I ran the same and it is working fine I am not able to see any problem with the below code can someone please help me understand from the interview's perspective why he said this is not the right way.



        trigger ContactTrigger on Contact (after insert, before Insert, before update, after update) {

    if(Trigger.operationType == triggerOperation.AFTER_INSERT || Trigger.operationType == triggerOperation.AFTER_UPDATE) {
    set<Id> IdSet =new set<Id>();
    for(Contact cot : trigger.new) {
    if(cot.accountID != null) {
    IdSet.add(cot.accountId);
    }
    }

    Integer contactListCount = [Select count() from contact where accountID IN: IdSet];

    if(contactListCount > 2) {
    for(contact cop : trigger.new) {
    cop.addError('cannot have more than 2 contacts per account');
    }
    }
    }
    }









    share|improve this question



























      1












      1








      1








      Yesterday I got rejected from a job interview because the interviewer asked me to write a trigger to limit the number of contacts per account and I wrote exactly the below but he said this won't work and it is not the correct way to write the same.
      I ran the same and it is working fine I am not able to see any problem with the below code can someone please help me understand from the interview's perspective why he said this is not the right way.



          trigger ContactTrigger on Contact (after insert, before Insert, before update, after update) {

      if(Trigger.operationType == triggerOperation.AFTER_INSERT || Trigger.operationType == triggerOperation.AFTER_UPDATE) {
      set<Id> IdSet =new set<Id>();
      for(Contact cot : trigger.new) {
      if(cot.accountID != null) {
      IdSet.add(cot.accountId);
      }
      }

      Integer contactListCount = [Select count() from contact where accountID IN: IdSet];

      if(contactListCount > 2) {
      for(contact cop : trigger.new) {
      cop.addError('cannot have more than 2 contacts per account');
      }
      }
      }
      }









      share|improve this question
















      Yesterday I got rejected from a job interview because the interviewer asked me to write a trigger to limit the number of contacts per account and I wrote exactly the below but he said this won't work and it is not the correct way to write the same.
      I ran the same and it is working fine I am not able to see any problem with the below code can someone please help me understand from the interview's perspective why he said this is not the right way.



          trigger ContactTrigger on Contact (after insert, before Insert, before update, after update) {

      if(Trigger.operationType == triggerOperation.AFTER_INSERT || Trigger.operationType == triggerOperation.AFTER_UPDATE) {
      set<Id> IdSet =new set<Id>();
      for(Contact cot : trigger.new) {
      if(cot.accountID != null) {
      IdSet.add(cot.accountId);
      }
      }

      Integer contactListCount = [Select count() from contact where accountID IN: IdSet];

      if(contactListCount > 2) {
      for(contact cop : trigger.new) {
      cop.addError('cannot have more than 2 contacts per account');
      }
      }
      }
      }






      apex trigger






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Apr 14 at 6:01









      sanket kumar

      3,6482427




      3,6482427










      asked Apr 14 at 4:56









      gs650xgs650x

      168111




      168111






















          3 Answers
          3






          active

          oldest

          votes


















          1














          This is the best example to use child soql to handle bulky records..
          Please see the Below logic..



          trigger ContactTrigger on Contact (after insert, before Insert, before update, after update) {
          if ((Trigger.isInsert || Trigger.isUpdate) && Trigger.isAfter) {
          Set<Id> setofAccountId = new Set<Id>();
          for(Contact objCon : trigger.new)
          setofAccountId.add(objCon.accountid)
          //Get all account contact related values
          Map<Id,Account> mapofAccIdToContacts = new Map<Id,Account>([Select Id,(Select Id From Contacts) From Account Where Id IN : setofAccountId]);
          for(Contact objCon : trigger.new){
          if(mapofAccIdToContacts.containskey(objCon.accountID) && mapofAccIdToContacts.get(objCon.accountID).Contacts.size() > 2)
          objCon.addError('cannot have more than 2 contacts per account');
          }
          }
          }





          share|improve this answer


























          • Thank you for responding but what if the account query fetch more than 50K records

            – gs650x
            Apr 14 at 10:37











          • For that case, you can use where clause in soql to store accountid in the set. I update the answer, Please have a look

            – sarvesh kumar
            Apr 14 at 11:20











          • Thank you so much!

            – gs650x
            Apr 14 at 11:45



















          3














          This trigger is not bulkified. It can't handle more than one account at a time. To fix the problem, an aggregate query would have been the most efficient solution. Here's my version of this trigger:



          trigger BlockMoreThan2ContactOnAccount on Contact (after insert, after update, after undelete) {
          Set<Id> accountIds = new Set<Id>();
          for(Contact record: Trigger.new) {
          accountIds.add(record.AccountId);
          }
          accountIds.remove(null);
          Set<Id> morethan2Contacts = new Map<Id, AggregateResult>([
          SELECT AccountId Id
          FROM Contact
          WHERE AccountId = :accountIds
          GROUP BY AccountId
          HAVING COUNT(Id) > 2]).keySet();
          for(Contact record: Trigger.new) {
          if(moreThan2Contacts.contains(record.AccountId)) {
          record.AccountId.addError('You may not have more than 2 contacts per account.');
          }
          }
          }


          You should always look for opportunities to use aggregate results (such as summing, counting, and finding averages) for performance reasons.






          share|improve this answer
























          • Thank you so much, I will always keep this in mind

            – gs650x
            Apr 14 at 16:47



















          1














          I would recommend creating a developer account to test said code with some debug statements to see what the output is.



          Your soql query returns the total number of contacts in each account. This will work if there is only one account in the org, But it won't if there're more.Example: if there are 3 accounts with 4 contacts each, the output of contactListCount will be 12.



          Also, in your 2nd loop you are looping again over Trigger.new, even if you did manage to filter out the accounts with 2+ contacts and added them to a new list, you ignored it by running over Trigger.new again and not over the new list.






          share|improve this answer


























          • Thank you for responding, I got the error.

            – gs650x
            Apr 14 at 10:37












          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "459"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f257764%2fcontact-trigger-to-limit-an-account-to-not-have-more-than-2-contacts%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          This is the best example to use child soql to handle bulky records..
          Please see the Below logic..



          trigger ContactTrigger on Contact (after insert, before Insert, before update, after update) {
          if ((Trigger.isInsert || Trigger.isUpdate) && Trigger.isAfter) {
          Set<Id> setofAccountId = new Set<Id>();
          for(Contact objCon : trigger.new)
          setofAccountId.add(objCon.accountid)
          //Get all account contact related values
          Map<Id,Account> mapofAccIdToContacts = new Map<Id,Account>([Select Id,(Select Id From Contacts) From Account Where Id IN : setofAccountId]);
          for(Contact objCon : trigger.new){
          if(mapofAccIdToContacts.containskey(objCon.accountID) && mapofAccIdToContacts.get(objCon.accountID).Contacts.size() > 2)
          objCon.addError('cannot have more than 2 contacts per account');
          }
          }
          }





          share|improve this answer


























          • Thank you for responding but what if the account query fetch more than 50K records

            – gs650x
            Apr 14 at 10:37











          • For that case, you can use where clause in soql to store accountid in the set. I update the answer, Please have a look

            – sarvesh kumar
            Apr 14 at 11:20











          • Thank you so much!

            – gs650x
            Apr 14 at 11:45
















          1














          This is the best example to use child soql to handle bulky records..
          Please see the Below logic..



          trigger ContactTrigger on Contact (after insert, before Insert, before update, after update) {
          if ((Trigger.isInsert || Trigger.isUpdate) && Trigger.isAfter) {
          Set<Id> setofAccountId = new Set<Id>();
          for(Contact objCon : trigger.new)
          setofAccountId.add(objCon.accountid)
          //Get all account contact related values
          Map<Id,Account> mapofAccIdToContacts = new Map<Id,Account>([Select Id,(Select Id From Contacts) From Account Where Id IN : setofAccountId]);
          for(Contact objCon : trigger.new){
          if(mapofAccIdToContacts.containskey(objCon.accountID) && mapofAccIdToContacts.get(objCon.accountID).Contacts.size() > 2)
          objCon.addError('cannot have more than 2 contacts per account');
          }
          }
          }





          share|improve this answer


























          • Thank you for responding but what if the account query fetch more than 50K records

            – gs650x
            Apr 14 at 10:37











          • For that case, you can use where clause in soql to store accountid in the set. I update the answer, Please have a look

            – sarvesh kumar
            Apr 14 at 11:20











          • Thank you so much!

            – gs650x
            Apr 14 at 11:45














          1












          1








          1







          This is the best example to use child soql to handle bulky records..
          Please see the Below logic..



          trigger ContactTrigger on Contact (after insert, before Insert, before update, after update) {
          if ((Trigger.isInsert || Trigger.isUpdate) && Trigger.isAfter) {
          Set<Id> setofAccountId = new Set<Id>();
          for(Contact objCon : trigger.new)
          setofAccountId.add(objCon.accountid)
          //Get all account contact related values
          Map<Id,Account> mapofAccIdToContacts = new Map<Id,Account>([Select Id,(Select Id From Contacts) From Account Where Id IN : setofAccountId]);
          for(Contact objCon : trigger.new){
          if(mapofAccIdToContacts.containskey(objCon.accountID) && mapofAccIdToContacts.get(objCon.accountID).Contacts.size() > 2)
          objCon.addError('cannot have more than 2 contacts per account');
          }
          }
          }





          share|improve this answer















          This is the best example to use child soql to handle bulky records..
          Please see the Below logic..



          trigger ContactTrigger on Contact (after insert, before Insert, before update, after update) {
          if ((Trigger.isInsert || Trigger.isUpdate) && Trigger.isAfter) {
          Set<Id> setofAccountId = new Set<Id>();
          for(Contact objCon : trigger.new)
          setofAccountId.add(objCon.accountid)
          //Get all account contact related values
          Map<Id,Account> mapofAccIdToContacts = new Map<Id,Account>([Select Id,(Select Id From Contacts) From Account Where Id IN : setofAccountId]);
          for(Contact objCon : trigger.new){
          if(mapofAccIdToContacts.containskey(objCon.accountID) && mapofAccIdToContacts.get(objCon.accountID).Contacts.size() > 2)
          objCon.addError('cannot have more than 2 contacts per account');
          }
          }
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Apr 14 at 11:19

























          answered Apr 14 at 8:30









          sarvesh kumarsarvesh kumar

          10418




          10418













          • Thank you for responding but what if the account query fetch more than 50K records

            – gs650x
            Apr 14 at 10:37











          • For that case, you can use where clause in soql to store accountid in the set. I update the answer, Please have a look

            – sarvesh kumar
            Apr 14 at 11:20











          • Thank you so much!

            – gs650x
            Apr 14 at 11:45



















          • Thank you for responding but what if the account query fetch more than 50K records

            – gs650x
            Apr 14 at 10:37











          • For that case, you can use where clause in soql to store accountid in the set. I update the answer, Please have a look

            – sarvesh kumar
            Apr 14 at 11:20











          • Thank you so much!

            – gs650x
            Apr 14 at 11:45

















          Thank you for responding but what if the account query fetch more than 50K records

          – gs650x
          Apr 14 at 10:37





          Thank you for responding but what if the account query fetch more than 50K records

          – gs650x
          Apr 14 at 10:37













          For that case, you can use where clause in soql to store accountid in the set. I update the answer, Please have a look

          – sarvesh kumar
          Apr 14 at 11:20





          For that case, you can use where clause in soql to store accountid in the set. I update the answer, Please have a look

          – sarvesh kumar
          Apr 14 at 11:20













          Thank you so much!

          – gs650x
          Apr 14 at 11:45





          Thank you so much!

          – gs650x
          Apr 14 at 11:45













          3














          This trigger is not bulkified. It can't handle more than one account at a time. To fix the problem, an aggregate query would have been the most efficient solution. Here's my version of this trigger:



          trigger BlockMoreThan2ContactOnAccount on Contact (after insert, after update, after undelete) {
          Set<Id> accountIds = new Set<Id>();
          for(Contact record: Trigger.new) {
          accountIds.add(record.AccountId);
          }
          accountIds.remove(null);
          Set<Id> morethan2Contacts = new Map<Id, AggregateResult>([
          SELECT AccountId Id
          FROM Contact
          WHERE AccountId = :accountIds
          GROUP BY AccountId
          HAVING COUNT(Id) > 2]).keySet();
          for(Contact record: Trigger.new) {
          if(moreThan2Contacts.contains(record.AccountId)) {
          record.AccountId.addError('You may not have more than 2 contacts per account.');
          }
          }
          }


          You should always look for opportunities to use aggregate results (such as summing, counting, and finding averages) for performance reasons.






          share|improve this answer
























          • Thank you so much, I will always keep this in mind

            – gs650x
            Apr 14 at 16:47
















          3














          This trigger is not bulkified. It can't handle more than one account at a time. To fix the problem, an aggregate query would have been the most efficient solution. Here's my version of this trigger:



          trigger BlockMoreThan2ContactOnAccount on Contact (after insert, after update, after undelete) {
          Set<Id> accountIds = new Set<Id>();
          for(Contact record: Trigger.new) {
          accountIds.add(record.AccountId);
          }
          accountIds.remove(null);
          Set<Id> morethan2Contacts = new Map<Id, AggregateResult>([
          SELECT AccountId Id
          FROM Contact
          WHERE AccountId = :accountIds
          GROUP BY AccountId
          HAVING COUNT(Id) > 2]).keySet();
          for(Contact record: Trigger.new) {
          if(moreThan2Contacts.contains(record.AccountId)) {
          record.AccountId.addError('You may not have more than 2 contacts per account.');
          }
          }
          }


          You should always look for opportunities to use aggregate results (such as summing, counting, and finding averages) for performance reasons.






          share|improve this answer
























          • Thank you so much, I will always keep this in mind

            – gs650x
            Apr 14 at 16:47














          3












          3








          3







          This trigger is not bulkified. It can't handle more than one account at a time. To fix the problem, an aggregate query would have been the most efficient solution. Here's my version of this trigger:



          trigger BlockMoreThan2ContactOnAccount on Contact (after insert, after update, after undelete) {
          Set<Id> accountIds = new Set<Id>();
          for(Contact record: Trigger.new) {
          accountIds.add(record.AccountId);
          }
          accountIds.remove(null);
          Set<Id> morethan2Contacts = new Map<Id, AggregateResult>([
          SELECT AccountId Id
          FROM Contact
          WHERE AccountId = :accountIds
          GROUP BY AccountId
          HAVING COUNT(Id) > 2]).keySet();
          for(Contact record: Trigger.new) {
          if(moreThan2Contacts.contains(record.AccountId)) {
          record.AccountId.addError('You may not have more than 2 contacts per account.');
          }
          }
          }


          You should always look for opportunities to use aggregate results (such as summing, counting, and finding averages) for performance reasons.






          share|improve this answer













          This trigger is not bulkified. It can't handle more than one account at a time. To fix the problem, an aggregate query would have been the most efficient solution. Here's my version of this trigger:



          trigger BlockMoreThan2ContactOnAccount on Contact (after insert, after update, after undelete) {
          Set<Id> accountIds = new Set<Id>();
          for(Contact record: Trigger.new) {
          accountIds.add(record.AccountId);
          }
          accountIds.remove(null);
          Set<Id> morethan2Contacts = new Map<Id, AggregateResult>([
          SELECT AccountId Id
          FROM Contact
          WHERE AccountId = :accountIds
          GROUP BY AccountId
          HAVING COUNT(Id) > 2]).keySet();
          for(Contact record: Trigger.new) {
          if(moreThan2Contacts.contains(record.AccountId)) {
          record.AccountId.addError('You may not have more than 2 contacts per account.');
          }
          }
          }


          You should always look for opportunities to use aggregate results (such as summing, counting, and finding averages) for performance reasons.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Apr 14 at 13:55









          sfdcfoxsfdcfox

          266k13212459




          266k13212459













          • Thank you so much, I will always keep this in mind

            – gs650x
            Apr 14 at 16:47



















          • Thank you so much, I will always keep this in mind

            – gs650x
            Apr 14 at 16:47

















          Thank you so much, I will always keep this in mind

          – gs650x
          Apr 14 at 16:47





          Thank you so much, I will always keep this in mind

          – gs650x
          Apr 14 at 16:47











          1














          I would recommend creating a developer account to test said code with some debug statements to see what the output is.



          Your soql query returns the total number of contacts in each account. This will work if there is only one account in the org, But it won't if there're more.Example: if there are 3 accounts with 4 contacts each, the output of contactListCount will be 12.



          Also, in your 2nd loop you are looping again over Trigger.new, even if you did manage to filter out the accounts with 2+ contacts and added them to a new list, you ignored it by running over Trigger.new again and not over the new list.






          share|improve this answer


























          • Thank you for responding, I got the error.

            – gs650x
            Apr 14 at 10:37
















          1














          I would recommend creating a developer account to test said code with some debug statements to see what the output is.



          Your soql query returns the total number of contacts in each account. This will work if there is only one account in the org, But it won't if there're more.Example: if there are 3 accounts with 4 contacts each, the output of contactListCount will be 12.



          Also, in your 2nd loop you are looping again over Trigger.new, even if you did manage to filter out the accounts with 2+ contacts and added them to a new list, you ignored it by running over Trigger.new again and not over the new list.






          share|improve this answer


























          • Thank you for responding, I got the error.

            – gs650x
            Apr 14 at 10:37














          1












          1








          1







          I would recommend creating a developer account to test said code with some debug statements to see what the output is.



          Your soql query returns the total number of contacts in each account. This will work if there is only one account in the org, But it won't if there're more.Example: if there are 3 accounts with 4 contacts each, the output of contactListCount will be 12.



          Also, in your 2nd loop you are looping again over Trigger.new, even if you did manage to filter out the accounts with 2+ contacts and added them to a new list, you ignored it by running over Trigger.new again and not over the new list.






          share|improve this answer















          I would recommend creating a developer account to test said code with some debug statements to see what the output is.



          Your soql query returns the total number of contacts in each account. This will work if there is only one account in the org, But it won't if there're more.Example: if there are 3 accounts with 4 contacts each, the output of contactListCount will be 12.



          Also, in your 2nd loop you are looping again over Trigger.new, even if you did manage to filter out the accounts with 2+ contacts and added them to a new list, you ignored it by running over Trigger.new again and not over the new list.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Apr 14 at 11:21

























          answered Apr 14 at 6:17









          JsonJson

          463522




          463522













          • Thank you for responding, I got the error.

            – gs650x
            Apr 14 at 10:37



















          • Thank you for responding, I got the error.

            – gs650x
            Apr 14 at 10:37

















          Thank you for responding, I got the error.

          – gs650x
          Apr 14 at 10:37





          Thank you for responding, I got the error.

          – gs650x
          Apr 14 at 10:37


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Salesforce Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f257764%2fcontact-trigger-to-limit-an-account-to-not-have-more-than-2-contacts%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Plaza Victoria

          Brian Clough

          Cáceres