The logic of this class is really confused. I'm going to sketch out some of the specific problems, but it needs to be rewritten more or less from scratch.
string accname ;
for(Account ac : acc)
{
accid = ac.id ;
accname = ac.contact_name__c ;
system.debug('accid....'+accid);
system.debug('accname....'+accname);
}
This doesn't make sense. You're taking in a list of Accounts, and then populating a variable with the properties of exactly one of them. What's going to happen when someone updates or inserts more than one Account? Your code's behavior is going to be pretty unexpected, because it picks one Account's information and then later applies it across multiple Accounts. I would strongly recommend completing Bulk Apex Triggers on Trailhead.
List<Account> acclist = New list<Account>();
acclist = [select name,id,contact_name__c,(select name,id from contacts) from account where id = :accid];
You don't need to initialize lists that you are going to assign a query result to.
Your query here only selects one Account, regardless of how many Accounts were touched by the trigger. Again I'd recommend the Bulk Triggers module linked above.
for(Account a : acclist)
{
for(contact con : a.contacts)
{
if(accname != con.name)
{
System.debug('accname....'+accname);
Contact c = New Contact();
c.Lastname = accname ;
c.accountid = accid ;
Conlist.add(c);
system.debug('conlist....'+conlist);
}
}
}
update conlist ;
This logic just doesn't make sense. A great strategy to address this kind of problem is called "rubber-duck debugging": explain this logic to your rubber duck, or some other inanimate prop. Forcing yourself to state the logic in words will often reveal the bug.
So here, you're looping over Accounts, then the Contacts of those Accounts. If any Contact's name is not equal to the name of the one Account you picked out in the first for
loop above (not the name of its associated Account, a
), you create a new Contact with the same name as the Account and add it to a list.
Notice that if your Account has no Contacts, your code does nothing. If it does have Contacts, your code will create a new one for each existing Contact that doesn't match accname
.
That is definitely not what you want to do, but it's not clear what the original intent of the loops was.
Finally, you perform a DML update
operation on the Contacts. That won't work because you cannot update records without an Id (i.e., that do not exist in the database), and you just created these Contact records in memory above. This will definitely throw an exception if execution ever gets to this point.
Your final implementation will certainly need to use something like the "collect-query-update/insert" pattern. You'll start by identifying the set of affected Accounts (plural - always work in collections), query for additional information (Contacts) if needed, iterate to create new records as needed, and finally perform one DML insert to create records.