function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Nisar AhmedNisar Ahmed 

Restricting a object to have only one primary related object record.

Hi All,

 

I have 2 custom objects by name 'Customer__c' and 'Address__c'.

Address object has a look up field of customer. It also has a picklist field 'Type__c' with values 'Primary' and 'Secondary' indicating the primary and secondary addresses for the customer object.

 

Now I want to restrict the customer to have only one 'Primary' address record but it can have multiple 'Secondary' address records. 

 

I have written the following trigger to accomplish this.

trigger primaryAddressDupPreventionV2 on Address__c (before insert, before update) {

	List<Address__c> Addr_List = new List<Address__c>();
	
	List<Address__c> addr_temp = System.Trigger.new;
    Customer__c cust = [select Id,Name from Customer__c where id=:addr_temp[0].Customer__c];

	try{
		for (Integer i=0;i<trigger.new.size();i++) {
			Addr_list = [Select Id, Name, Customer__c, Type__c from Address__c 
		                                where Customer__c =: cust.Id and Address__c.Type__c = 'Primary' and Id != null limit 1];
			system.debug('Addr List Size: '+Addr_list.size());
			system.debug('Addr List: '+Addr_list);
			
			if(Addr_List.size()== 0 && trigger.new[i].Type__c == 'Secondary'){
				trigger.new[i].Type__c.addError('Primary Address does not exist');
			}
			if(trigger.isInsert && Addr_List.size()>0 && Addr_List.get(0).Type__c == 'Primary' && trigger.new[i].Type__c == 'Primary'){
				trigger.new[i].Type__c.addError('Only one Primary Address should exist');
			}
		}
	}catch (DmlException e1) {
     	System.debug(e1.getMessage() );     
    }catch (TypeException e2) {
     	System.debug(e2.getMessage() );     
    }
}

 The trigger is working fine while inserting records. But fails during update operation.

 

Could anyone please let me know where I have gone wrong or any workaround to accomplish the same.

Any help will be highly appreciated.

Alex.AcostaAlex.Acosta

For one thing, this trigger is not bulk safe in case of mass updates. Can you further explain why it fails on updates? I can see it fail if your current updated record is its primary address and it's changed to secondary. Is this the issue? 

Nisar AhmedNisar Ahmed

Hi Alex,

 

Yes, you are right it fails when we update the current record from 'Primary' to 'Secondary'.

i.e., When we are creating a new record it works fine and restricts the user from creating another address record with 'Primary' value. But when we are editing the same record(or any existing record with value 'Secondary') and changing the value from 'Secondary' to 'Primary', the trigger fails to restrict it from saving.

 

What may be the problem here? Waiting for your valuable reply.

And also, What we can do to the trigger to work for mass updates.

Alex.AcostaAlex.Acosta

To make your trigger bulk friendly, please remove all queries inside your loops. What you need to so is query everything you need outside before hand. The issue you're having currently with updates is because of your if statement....

if(Addr_List.size()== 0 && trigger.new[i].Type__c == 'Secondary'){
	trigger.new[i].Type__c.addError('Primary Address does not exist');
}

 This needs to be altered to validate what you currently have in place since your query will pull in your current record. Something alone these lines

 

if((Trigger.isInsert && Addr_List.size()== 0 && trigger.new[i].Type__c == 'Secondary') || (Trigger.isUpdate && trigger.new[i].Type__c == 'Secondary' && trigger.old[i].Type == 'Primary')){	 
trigger.new[i].Type__c.addError('Primary Address does not exist');
}

 

The following are the best practices for this design pattern:
• Minimize the number of data manipulation language (DML) operations by adding records to collections and performing
DML operations against these collections.
• Minimize the number of SOQL statements by preprocessing records and generating sets, which can be placed in single
SOQL statement used with the IN clause.

 

For more information on how to make your trigger bulk friendly please look at page 92. http://www.salesforce.com/us/developer/docs/apexcode/salesforce_apex_language_reference.pdf They do provide good examples of what to do and how to handle different situations.

 

Meenu sharma 10Meenu sharma 10
Hi Nisar,

I am having same requirement.
If you have the solution then please let me know and help me out here.