0

I am trying to create a Trigger which will prevent deletion of Account which has atleast one contact linked to it. But its not working. Here is my code

trigger AccountDeleteonPrevention on Account (before delete) {
    
    if(Trigger.isBefore && Trigger.isDelete){
           for(Account acc: Trigger.old){
                          
             if(acc.Contacts.size()>0){
                   acc.addError('You cannot delete this account');
                   
               }          
       
    }
        
    }
   
}

When Im deleting Accounts which have contacts in my org they are getting deleted. Also I see that in debugging the value of account.Contacts.size() comes to be 0 which is strange. Thats the reason my if block is not getting evaluated. I am unable to understand my mistake here. Please help

3 Answers 3

2

If you want to add an error when you are trying to delete account than you need to

  1. Retrieve all related contacts

  2. Loop through each contact and add AccountId to Set

  3. Loop through accounts and add an error if account contains any contact

    trigger Account on Account (before delete) {
    
       if (Trigger.isBefore && Trigger.isDelete) {
          List<Contact> relatedContacts = [SELECT AccountId FROM Contact WHERE AccountId IN : Trigger.oldMap.keySet()];
    
          Set<Id> accIds = new Set<Id>();
          for (Contact contact : relatedContacts) {
              accIds.add(contact.accountId);
          }
    
          for (Account account : trigger.old) {
             if (accIds.contains(account.Id)) {
                 account.addError('You cannot delete this account');
             }
          }    
       }
    }
    

enter image description here

4
  • Thanks Kate it works. But I had a doubt. I saw an online example where a relationship SOQL query is done as follows: List<Account> acc=[select Name , (Select LastName from contacts) from Account Limit 10... then to get the no of contacts the following was done which directly gave the number of contacts for(Account acct:acc){ system.debug('####'+acct.contacts.size()); } So I was trying the same concept to get if size of this list of contacts is more than 0 means it has a contact so dont delete the account. Why wouldnt it work?
    – Amax1
    Commented May 20, 2022 at 8:40
  • To do the account.Contacts is a relationship SOQL Query mandatory?
    – Amax1
    Commented May 20, 2022 at 9:17
  • Yes, if you query Contacts from Account [SELECT Id, (SELECT LastName FROM Contacts) FROM Account WHERE Id IN : Trigger.oldMap.keySet()] then you will be able to use account.Contacts.size(). By default you do not have an access in triggers to Contacts (and to other relations as well). That is why you need to query that fields and then you can relate to them in your code Commented May 20, 2022 at 9:29
  • Thanks a lot Kate !!. Really cleared the concepts along with getting the right answer !! :D
    – Amax1
    Commented May 20, 2022 at 9:36
0

How are you getting the Contacts??

Basically, your code is getting nothing when you say acc.Contacts.

Try debugging it in the System debug and check what is the value in your acc.Contacts.

trigger AccountDeleteonPrevention on Account (before delete) {
    
    if(Trigger.isBefore && Trigger.isDelete){
           for(Account acc: Trigger.old){
             System.debug('## Account>Contacts --> '+  acc.Contacts); // According to me This is not list of contacts and that's the issue here.
             if(acc.Contacts.size()>0){
                   acc.addError('You cannot delete this account');
                   
               }          
       
    }
        
    }
   
}

Solution: I think you should create a field to maintain the Contact record count on the Account and then add that field to your condition.

1
  • Its coming as blank. Just blank paranthesis. Actualy I got the Contacts from this online example where we use SOQL Query List<Account> acc=[select Name , (Select LastName from Contacts) from Account Limit 10]; for(Account acct:acc){ system.debug('####'+acct.Contacts.size()); } Is it possible directly without creating a field?
    – Amax1
    Commented May 20, 2022 at 8:25
-2

Maybe u can try this as well

trigger demoAcct on Account (before delete) {
    for(Account ac:trigger.old){
        List<Contact> relatedConList = [Select AccountId from Contact Where AccountId=: ac.Id];
        if(relatedConList.size()>0){
            ac.addError('You cannot delete this account');
        }
    }
}
1
  • 2
    You are using SOQL Query inside a for loop. This is considered bad practice as it hits governor limits.
    – Amax1
    Commented Oct 6, 2022 at 11:27

You must log in to answer this question.

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