I'm stuck here and not sure why this code is not working. I want to throw error if the child record (Contact)is more than 5 records per Parent record (Account)
Question: I want to restrict the user to create a child record for every parent record.
say each parent record can have upto 5 child records.
Parent: Account
Child: Contact
I have created a custom field in the Account object to track the number of counts of Contact.
Here is my code:
trigger triggerContact on Contact (before insert, before update, after insert, after update, after delete) {
Integer maxChildRecord = 5;
List<Contact> contacts = Trigger.isDelete ? Trigger.old : Trigger.new;
Set<Id> acctIds = new Set<Id>();
for (Contact c : contacts) {
if (c.AccountId != null) {
acctIds.add(c.AccountId);
}
}
Map<Id, Account> accountMap = new Map<Id, Account>();
for (AggregateResult ar : [SELECT AccountId AcctId, Count(id) ContactCount
FROM Contact
WHERE AccountId in: acctIds
GROUP BY AccountId]){
accountMap.put((Id)ar.get('AcctId'), new Account(Id = (Id)ar.get('AcctId'), Contact_Count__c = (Integer)ar.get('ContactCount')));
}
List<Account> acctsToRollup = new List<Account>();
for(Account account : accountMap.values()) {
Integer dbChildCount = (Integer)account.Contact_Count__c;
Account a = new Account();
a.Id = account.Id;
a.Contact_Count__c = (Integer)account.Contact_Count__c;
if (dbChildCount > maxChildRecord){
account.addError('can not add more child!');
}else {
acctsToRollup.add(a);
}
}
if (acctsToRollup.size() > 0) {
update acctsToRollup;
}
Best Answer
There are couple of logical issues
The
addError
needs to be on the object's trigger context. In this scenario add the Error on the Account Trigger and not on the contact. In your Contact trigger context, addError won't throw an error unless you add an error on the triggered contact record. I would simply move the addError part of the logic to a before update trigger on the Account.The above logic could also be a simple validation rule.
Few code pointers, do not have logic inside Trigger and try to move your logic to a Helper class or adopt a Trigger Framework for better maintainability.
Update
Now since your preference is to keep all the logic on Contact itself here is how I would modify the code,
Carefully note how I am storing all contacts for the Account that came in through (trigger.new/trigger.old) using the data structure
Map<Id, List<Contact>>