You need to sign in to do that
Don't have an account?
Interesting problem
I have a custom object with a "Set Default" Checkbox to indicate that that record is the default record for another process. Obviously I only want one default record at a time. I am writing a trigger to set all the other records checkbox to false when a new or updated records checkbox is set to true. Here is my Code:
trigger SetDefault on Workflow_Types__c (before insert, before update) { List<Workflow_Types__c> wt = new List<Workflow_Types__c>([Select id, default__c from Workflow_Types__c]); Integer size = wt.size(); for (Workflow_Types__c w: Trigger.new){ if (w.Default__c == True){ for (Integer i = 0; i < wt.size(); i++){ if (wt[i].id != w.id){ wt[i].Default__c = False; //update wt[i]; }else{ Workflow_Types__c temp = wt.remove(i); system.assertEquals(w.id, temp.id); system.assertEquals(wt.size(), size-1); } } } } update wt; }
The problem is that even though I am trying to remove the record that calls the trigger and the assertions are passed for some reason it is still trying to recursively update the calling record when I call update wt, and gives me an error. If I uncomment the line //update wt[i]; and comment the other update it does work, but I am afraid of possibly hitting governor limits by putting the DML statement in the for loops. Any ideas would be appreciated.
Thanks
Edit: I have determined that the behaviour I described only happens when there are only two records in the object. If I add more objects I have no problems
You are updating Workflow_Types__c in trigger which get triggered before update and insert of Workflow_Types__c. You are creating a scenario which is causing cascading. You need to rethink over your approach to update Workflow_Types__c.
Thanks
Ankit Arora
Blog | Facebook | Blog Page
All Answers
trigger SetDefault on Workflow_Types__c (before insert, before update) {
List<Workflow_Types__c> wt = new List<Workflow_Types__c>([Select id, default__c from Workflow_Types__c where Default__c = true]);
for (Workflow_Types__c w: Trigger.new){
if (w.Default__c == True){
for (Workflow_Types__c wts:wt){
if (wts.id != w.id){
wts.Default__c = False;
}
}
}
}
update wt;
}
That is a better way to write the trigger, however it has not solved the issue. I think that the trigger is upset cause it is recursively calling itself, but how would i bypass that?
Is there an error message it is throwing?
You are updating Workflow_Types__c in trigger which get triggered before update and insert of Workflow_Types__c. You are creating a scenario which is causing cascading. You need to rethink over your approach to update Workflow_Types__c.
Thanks
Ankit Arora
Blog | Facebook | Blog Page
Does this work?
trigger SetDefault on Workflow_Types__c (before insert, before update) {
List<Workflow_Types__c> wt = new List<Workflow_Types__c>([Select id, default__c from Workflow_Types__c where Default__c = true]);
if wt.size() >1{
for (Workflow_Types__c w: Trigger.new){
if (w.Default__c == True){
for (Workflow_Types__c wts:wt){
if (wts.id != w.id){
wts.Default__c = False;
}
}
}
}
update wt;
}
}
@ Anit - I did rethink and I think I got it working. I still need to write a test class for it but use testing seemed to work.
I added a test case so that my last section looks like this:
needsUpdate gets set if wt gets updated at all, but only then. This way it avoids the cascade effect. Thanks for all you help guys.