You need to sign in to do that
Don't have an account?
How to check for an existing relationship between two Contact records
In our org we have some piece of apex code which allows users to create a related contact to an existing contact. It can be done by clicking a button on the custom related list situated at the bottom of the contact record.
The problem I am facing is, users are able to create multiple relationships with same contact. And also a contact can be linked to itself as well. I solved the second part saying if the Ids of two records are same, dont create the relation.
But the tricky one is the first part. There is a junction object called Contact_connector in between them. which is inserted everytime the relation is created. If there is a way to put in both the existing record Id and duplicated record and tranverse through the Contact_connectorID and check if thats existing then I can say dont create.
But am not finding a way to check whether the Contact_connectorId exists between them.
Would be a great help if any one can come up with a solution..
If you want for update operation also simply add before update like
trigger TriggerExistingRelation on SFDC_Contact_Connector__c (before insert,before update) {
}
But as per your requirement entire code is wrong. It won't work for Insert oparetion also.
Why because your requirement is to check the two records are same or not, But here in if condition your writing code for taking all record values but not perticular record.
//Get the list
List<SFDC_Contact_Connector__c> relrecs = [Select cl.Contact__c, cl.Related_Contact__c from SFDC_Contact_Connector__c cl where cl.Id IN :relids];
set<id> ContactsSet = new set<id>();
for(SFDC_Contact_Connector__c cl: relrecs)
{
ContactsSet.add(cl.Contact__c);
}
set<id> RelContsSet = new set<id>();
for(SFDC_Contact_Connector__c cl: relrecs)
{
RelcontsSet.add(cl.Related_Contact__c);
}
if(ContactsSet.contains(cl.Contact__c) && RelContsSet.contains(cl.Related_Contact__c))
for Example:-
cricket is junction object
Batsman and Bowlers are parents
Here i am creating two records in Cricket object
Cricketname1
sachin
Zaheer
Cricketname2
dravid
sreenth
The Next record should be allow if it is like this
Cricketname3
sachin
sreenth
But your code Doesn't allow this record why because it is checking all two record values
So here you have to check the values are in the same record are not
At the time only Cricketname3 record will allow.
So instead of set use map here
Map<id,id> ContactsSet = new Map<id,id>();
Map<id,id> RelContsSet = new Map<id,id>();
for(SFDC_Contact_Connector__c cl: relrecs) // use one loop is enough
{
ContactsSet.put(cl.Contact__c,cl.id);
RelcontsSet.add(cl.Related_Contact__c,cl.id );
}
So here Key is Different But Values are same
In if condition based on value(record id) you can check and then only return error
Better to use System.Debug(); For every step then your can find the errors easily
See some Map examples and follow up
Prem
All Answers
First thing you have to write a trigger Before insert event
In that trigger wrte a query for take all Records from Contact_connector.
Take two lists for that two look-up fields : contact and Child_contact , Both are bringing id only.
Now Whatever your inserting the record in Contact_connector, That will come to Trigger.New
Then Use if condition to check whether the same values are in the list or not.
If it is available return Error Message. Else it should be save.
Thanks
Prem
Thank you very much Prem..
That makes sense to me, will try doing that..
Cheers
Ven
Hi Prem.. I have written the following trigger..
trigger TriggerExistingRelation on SFDC_Contact_Connector__c (before insert) {
//Get all the Existing Relationship Record Ids
SFDC_Contact_Connector__c[] relconts = [Select Id, Contact__c, Related_Contact__c from SFDC_Contact_Connector__c];
set<id> relids = new set<id>();
for(SFDC_Contact_Connector__c cl : relconts)
{
relids.add(cl.Id);
}
//Get the list
List<SFDC_Contact_Connector__c> relrecs = [Select cl.Contact__c, cl.Related_Contact__c from SFDC_Contact_Connector__c cl where cl.Id IN :relids];
set<id> ContactsSet = new set<id>();
for(SFDC_Contact_Connector__c cl: relrecs)
{
ContactsSet.add(cl.Contact__c);
}
set<id> RelContsSet = new set<id>();
for(SFDC_Contact_Connector__c cl: relrecs)
{
RelcontsSet.add(cl.Related_Contact__c);
}
for(SFDC_Contact_Connector__c cl: Trigger.new)
{
try{
if(ContactsSet.contains(cl.Contact__c) && RelContsSet.contains(cl.Related_Contact__c))
{
cl.addError('A relationship already exists with the same person');
}
}
catch (Exception ex){
// do nothing
}
}
}
It is working, But the problem is It is not allowing to create any new relationship with the existing records. Eg: If B is related to A and if I want to relate B to another record C it is not allowing me to do so..
If I choose list then I cant use contains function. So am confused of what to do now.. Is there any other way of checking all the existing records if they contain the pair of Contact Id and Related Contact Id
If you want for update operation also simply add before update like
trigger TriggerExistingRelation on SFDC_Contact_Connector__c (before insert,before update) {
}
But as per your requirement entire code is wrong. It won't work for Insert oparetion also.
Why because your requirement is to check the two records are same or not, But here in if condition your writing code for taking all record values but not perticular record.
//Get the list
List<SFDC_Contact_Connector__c> relrecs = [Select cl.Contact__c, cl.Related_Contact__c from SFDC_Contact_Connector__c cl where cl.Id IN :relids];
set<id> ContactsSet = new set<id>();
for(SFDC_Contact_Connector__c cl: relrecs)
{
ContactsSet.add(cl.Contact__c);
}
set<id> RelContsSet = new set<id>();
for(SFDC_Contact_Connector__c cl: relrecs)
{
RelcontsSet.add(cl.Related_Contact__c);
}
if(ContactsSet.contains(cl.Contact__c) && RelContsSet.contains(cl.Related_Contact__c))
for Example:-
cricket is junction object
Batsman and Bowlers are parents
Here i am creating two records in Cricket object
Cricketname1
sachin
Zaheer
Cricketname2
dravid
sreenth
The Next record should be allow if it is like this
Cricketname3
sachin
sreenth
But your code Doesn't allow this record why because it is checking all two record values
So here you have to check the values are in the same record are not
At the time only Cricketname3 record will allow.
So instead of set use map here
Map<id,id> ContactsSet = new Map<id,id>();
Map<id,id> RelContsSet = new Map<id,id>();
for(SFDC_Contact_Connector__c cl: relrecs) // use one loop is enough
{
ContactsSet.put(cl.Contact__c,cl.id);
RelcontsSet.add(cl.Related_Contact__c,cl.id );
}
So here Key is Different But Values are same
In if condition based on value(record id) you can check and then only return error
Better to use System.Debug(); For every step then your can find the errors easily
See some Map examples and follow up
Prem
Thank you very much Prem.. That was a great help.
A new concern came up now.. We do have millions of Relationship records in our org.. My trigger works fine in the sandbox but am worried about putting that onto the production, because a single query is going to return millions of record rows and may bounce into governor limits.. Whats the best way to limit the rows regarding this?? Is there a standard salesforce approach or Is that concern with our org??
Is there any way to search for the related contacts of the new record contacts..?? using relationship queries or anything as such?..
For Newly created contact , how can you create/present the child records.
clearly explain what is your requirement.
if you want for related contacts means
List<Contact> varex=[select id,name,(select id,name from child_Contact__r) from Contact where Id in :Trigger.old];
if(varex.size()==0){
//message
}
else{
//return varex records ;
}
I will explain my requirement by the following cricket example.
Suppose I have players - sachin, Zaheer, Sreeshanth, Gambir, Raina ( which are already existing).
The trigger i am trying to wirte is for creating a relationship for existing contacts..
Existing Relations would be
Cricket1 - Sachin & Zaheer
Cricket2 - Sachin & Sreeshanth
Cricket3 - Gambir & Zaheer .........etc.
If another relationship is required with sachin - It should allow - Sachin & Raina.
where as if users by mistake try to relate Sachin & Zaheer agina that should fail. This is my requirement.
In the first approach you suggested..
SFDC_Contact_Connector__c[] relconts = [Select Id, Contact__c, Related_Contact__c from SFDC_Contact_Connector__c];
This is fetching all the relationship records and checking them against the new ones..
But there are more than a million reocrds in our org.. So firing this trigger would bounce into governor limits..
So now what I think is.. instead of fetching all the relationship records..
If relationship is to create between Sachin and Raina..
Get the existing relatioships on Sachin and existing relationships on Raina and check whether any of them match..
If it matches then display error..
Would be a great help if you could suggest a solution for this.. Thanks in advance
Hi Venkat,
Good Idea, But you must write query here, If sachin having more than 50,000 records at that time also you cross governor limits.
if it is not a problm means you can go through this way.
string str1,str2;
for(SFDC_Contact_Connector__c cl: Trigger.New)
{
str1=cl.cContact__c;
str2=cl.Related_Contact__c;
}
List<SFDC_Contact_Connector__c> relrecs = [Select cl.Contact__c, cl.Related_Contact__c from SFDC_Contact_Connector__c cl where cContact__c=str1 ];
Map<id,id> ContactsSet = new Map<id,id>();
Map<id,id> RelContsSet = new Map<id,id>();
for(SFDC_Contact_Connector__c cl: relrecs)
{
ContactsSet.put(cl.Contact__c,cl.id);
}
List<SFDC_Contact_Connector__c> relrecs123 = [Select cl.Contact__c, cl.Related_Contact__c from SFDC_Contact_Connector__c cl where cContact__c=str2 ];
for(SFDC_Contact_Connector__c cl: relrecs123)
{
ContactsSet.put(cl.Related_Contact__c,cl.id);
}
Here you get the id's of those existing records. then you can compare the id's , if it is same then display error.
===========================
But one simple way we have.
If we write query for checking two values are there in one record or not. like this
string str1,str2;
for(SFDC_Contact_Connector__c cl: Trigger.New)
{
str1=cl.cContact__c;
str2=cl.Related_Contact__c;
}
List<SFDC_Contact_Connector__c> relrecs = [Select cl.Contact__c, cl.Related_Contact__c from SFDC_Contact_Connector__c cl where cContact__c=str1 and Related_Contact__c=str2];
if(relrecs.size()>0){
// Error
}
else
//allow save
This is good Enough Right!!!!
Prem
Thanks very much Prem.. I understood the solution.. but when am trying to save the trigger.. It is showing error for 'Contact__c = str1'
Error: Compile Error: unexpected token: 'str1
It is not accepting the reference as string.. Is it because the Contact is Id?
Write like this
Contact__c =:str1
//Get all the Existing Relationship Record Ids
/*Cricket__c[] relconts = [Select Id, Batsman__c, Bowler__c from Cricket__c];
set<id> relids = new set<id>();
for(Cricket__c cl : relconts)
{
relids.add(cl.Id);
}
//Get the list
// List<Cricket__c> relrecs = [Select cl.Batsman__c, cl.Bowler__c from Cricket__c cl where cl.Id IN :relids];
set<id> ContactsSet = new set<id>();
for(Cricket__c cl: relrecs)
{
ContactsSet.add(cl.Batsman__c);
}
set<id> RelContsSet = new set<id>();
for(Cricket__c cl: relrecs)
{
RelcontsSet.add(cl.Bowler__c);
}*/
String str1,str2;
for(Cricket__c cl: Trigger.new)
{
str1=cl.Batsman__c;
str2=cl.Bowler__c;
/*System.Debug(cl.Bowler__c+'===================================='+cl.Batsman__c);
if(ContactsSet.contains(cl.Batsman__c) && RelContsSet.contains(cl.Bowler__c))
{
cl.addError('A relationship already exists with the same person');
}*/
}
List<Cricket__c> relrecs = [Select Batsman__c,Bowler__c from Cricket__c where Batsman__c=:str1 and Bowler__c=:str2];
if(relrecs.size()>0){
Trigger.New[0].addError('A relationship already exists with the same person');
}
}
Sorry my ignorance.. didnt notice that.. as am a apex starter..
Thats perfectly working..
That was really a great help Prem.. Thank you very much.. Thanks a lot..