3

I've a scenario where there are 2 objects(Trail-master and Vehicles-detail) and no edits is to be allowed on parent if there are no related child records. I've tried the below code but without any result. Can anyone help me on this?

trigger stopdel on Trail__c (before update) {
List<Trail__c> tList = [SELECT Id,(SELECT Id FROM Vehicles__r) FROM Trail__c WHERE Id IN:Trigger.new];
for(Trail__c t:tList){
    List<Vehicle__c> vList = t.getSObjects('Vehicles__r');
        if(vList.isEmpty()){ //getting null pointer exception at this line
            t.addError('you cannot delete');
        }
    }
}

3 Answers 3

6

You could also prevent edits by rolling up a count of child records and place a validation rule based on that rollup.

2
  • 2
    Tried this one as well, works fine. Would definitely prefer this over trigger!
    – Sagnik
    May 29, 2016 at 12:37
  • 2
    @Sagnik You should make this the accepted answer if it works best so others who come across this question will be led to the best answer.
    – Keith C
    May 29, 2016 at 14:23
3

From a quick check I just did on Account/Contact, it looks like the getSObjects method returns null when there are no child values instead of returning an empty list. (Not helpful or documented and a bit of a surprise.) Test code:

for (Account a : [select Name, (select Name from Contacts) from Account limit 3]) {
    System.debug('>>> d ' + a.getSObjects('Contacts'));
    System.debug('>>> s ' + a.Contacts);
}

outputs:

06:40:44.11 (18453282)|USER_DEBUG|[2]|DEBUG|>>> d null
06:40:44.11 (18616912)|USER_DEBUG|[3]|DEBUG|>>> s ()
06:40:44.11 (18781939)|USER_DEBUG|[2]|DEBUG|>>> d null
06:40:44.11 (18851803)|USER_DEBUG|[3]|DEBUG|>>> s ()
06:40:44.11 (19062520)|USER_DEBUG|[2]|DEBUG|>>> d (Contact:{AccountId=0015000000curPjAAI, Id=0035000001mZBEcAAO, Name=Test Person})
06:40:44.11 (19166666)|USER_DEBUG|[3]|DEBUG|>>> s (Contact:{AccountId=0015000000curPjAAI, Id=0035000001mZBEcAAO, Name=Test Person})

You could add an extra check for that null value, but if you use the "static" approach to accessing the list that problem doesn't occur and you get the expected empty list.

So change the line to:

List<Vehicle__c> vList = t.Vehicles__r;

The error message for the current code should be "you cannot edit"; as Shankish points out you need to handle "before delete" to deal with the delete case.

PS

In response to your comment, the error has to be added to the row instance that is in the trigger context so:

Trigger.newMap.get(t.Id).addError('you cannot edit');
2
  • Thanks Keith! I'm still getting an error of "SObject row does not allow errors" on the line where i'm trying to put the error message.
    – Sagnik
    May 29, 2016 at 12:17
  • @Sagnik See the PS.
    – Keith C
    May 29, 2016 at 12:23
1

If you want to prevent users from deleting the Trail record you will have to write Trigger on On Delete operation. Use Trigger.old for delete trigger while Trigger.new will work for Update trigger

trigger stopdel on Trail__c (before update, before delete)<br/>
{<br/>
 //the same code<br/>
 //write logic for delete with Trigger.old<br/>
}

You must log in to answer this question.

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