You actually can get that related list on the standard Salesforce Contact
...with a little work.
Since your Training_Record__c
is related to a single Contact__c
, and Contact__c
is related to a single standard Contact
, you could make a lookup field on Training_Record__c
that points to Contact
.
Once you have that, you can add the related list to your standard Contact
page layout(s).
This field would need to be populated via trigger (or pretty much anything that isn't a workflow rule + field update, because WFR field updates cannot use a formula to assign the value for lookup fields), but the code is simple enough.
// I assume that the relationship field on Training_Record__c is 'Contact__c'.
// I also assume that the relationship field between Contact__c and Contact is also
// called 'Contact__c'
// It takes extra effort to mentally juggle whether or not you're using the standard
// or custom version of an object, that's why re-using standard object names for
// custom objects is a bad idea.
trigger SetLookupToStdContact on Training_Record__c (before insert, before update){
// If your entire relationship hierarchy isn't established at the time that you
// insert Training_Record__c records, then you'll need another trigger
// to update child Training__c records when your Contact__c is related to a
// standard Contact.
// before insert, the Training_Record__c records won't have their Id, but
// they can have Contact__c populated.
Set<Id> customContactIds = new Set<Id>();
for(Training_Record__c tr :trigger.new){
customContactIds.add(tr.Contact__c);
}
customContactIds.remove(null);
Map<Id, Contact__c> customContactsMap = new Map<Id, Contact__c>([SELECT Id, Contact__c FROM Contact__c WHERE Id IN :customContactIds]);
// Because we're doing this in before triggers, we can update the record in
// trigger.new to avoid needing DML
for(Training_Record__c tr :trigger.new){
if(customContactsMap.containsKey(tr.Contact__c)){
tr.Standard_Contact__c = customContactsMap.get(tr.Contact__c).Contact__c;
}
}
}