+ Start a Discussion
bohemianguy100bohemianguy100 

run trigger code only when value changed

I have a trigger that assigns the account owner to the contact owner record when the contact is inserted or updated (before insert, before update).  I only want to execute code when the account on the contact changes.  If there is no change, I don't want to execute the code.

 

I can compare the account value on the contact using the trigger.new collection and the trigger.oldMap collection.  The code is factored out into a separate class using the trigger template pattern.

 

It is making it a little trickier to do the check and only run the code when the account changes.

 

Here is my class:

 

global class ContactAssignOwnership implements Triggers.HandlerInterface {
	
	Contact[] newCollection = trigger.new;
	Set<Id> accountIds = new Set<Id>();

	
	global void handle() {
		assignContactOwnership(getAccountIds());
	}
	
	private Set<Id> getAccountIds() {
		for(Contact c: newCollection) {
			accountIds.add(c.accountId);
		}
		return accountIds;
	}
	
	private void assignContactOwnership(Set<Id> accountIds) {
		Map<Id, Account> mapAccounts = new Map<Id, Account>([select Id, ownerId from Account where id in: accountIds]);
		
		for(Contact c : newCollection) {
			if(!mapAccounts.isEmpty() && mapAccounts.size() > 0) {
				if(mapAccounts.containsKey(c.accountId)) {
					c.OwnerId = mapAccounts.get(c.accountId).OwnerId;
				}
			}
		}
	}
}

 

I'd like to do the check in the handle method so that I don't run any unnecessary code.  However, how can I accomplish that for bulk?  I need to compare the account values for each record and see if they are different, then call the assignContactOwnership method which has a soql query, so I can't put that method inside a for loop or I'll hit limits.  Also, the oldMap isn't available in the before insert context so I'll get a null pointer exception if I use it there.

 

Any help is appreciated.

Thanks.

Best Answer chosen by Admin (Salesforce Developers) 
Kiran  KurellaKiran Kurella

 

You can modify getAccountIds and assignContactOwnership functions to accomplish it.

 

global class ContactAssignOwnership implements Triggers.HandlerInterface {
	
	Contact[] newCollection = trigger.new;
	Set<Id> accountIds = new Set<Id>();

	
	global void handle() {
		assignContactOwnership(getAccountIds());
	}
	
private Set<Id> getAccountIds() {
   for(Contact c: newCollection) {
      if (trigger.isInsert || c.AccountId!=trigger.oldMap.get(c.Id).AccountId) 

              accountIds.add(c.accountId);

	}
	return accountIds;
}
	
private void assignContactOwnership(Set<Id> accountIds) {

if (!accountIds.isEmpty()) {

		Map<Id, Account> mapAccounts = new Map<Id, Account>([select Id, ownerId from Account where id in: accountIds]);
		
		for(Contact c : newCollection) {
			if(!mapAccounts.isEmpty() && mapAccounts.size() > 0) {
				if(mapAccounts.containsKey(c.accountId)) {
					c.OwnerId = mapAccounts.get(c.accountId).OwnerId;
				}
			}
		}
	}
}
}
 

 

 

All Answers

Bhawani SharmaBhawani Sharma

List<Contact> updatedContacts = new List<Contact>();

for(Contact contact : Trigger.New) {
if(contact.AccountId != Trigger.oldMap.get(contact.Id).AccountId) {
updatedContacts.add(contact);

}
}

 

if(updatedContacts.size() > 0)

//Do your operation

bohemianguy100bohemianguy100

Thanks for your reply, but I'm still not clear how that will work within the handle method?  Also, I'm in a before trigger context.  I understand how to compare the values using the new and old collections.

Kiran  KurellaKiran Kurella

 

You can modify getAccountIds and assignContactOwnership functions to accomplish it.

 

global class ContactAssignOwnership implements Triggers.HandlerInterface {
	
	Contact[] newCollection = trigger.new;
	Set<Id> accountIds = new Set<Id>();

	
	global void handle() {
		assignContactOwnership(getAccountIds());
	}
	
private Set<Id> getAccountIds() {
   for(Contact c: newCollection) {
      if (trigger.isInsert || c.AccountId!=trigger.oldMap.get(c.Id).AccountId) 

              accountIds.add(c.accountId);

	}
	return accountIds;
}
	
private void assignContactOwnership(Set<Id> accountIds) {

if (!accountIds.isEmpty()) {

		Map<Id, Account> mapAccounts = new Map<Id, Account>([select Id, ownerId from Account where id in: accountIds]);
		
		for(Contact c : newCollection) {
			if(!mapAccounts.isEmpty() && mapAccounts.size() > 0) {
				if(mapAccounts.containsKey(c.accountId)) {
					c.OwnerId = mapAccounts.get(c.accountId).OwnerId;
				}
			}
		}
	}
}
}
 

 

 

This was selected as the best answer
bohemianguy100bohemianguy100

Thank you! Excellent solution!