Dilemma
As this page of the Apex docs indicates, you can’t just make a User trigger that updates a Contact or an Account, because it’s forbidden to modify those “non-setup” objects from a “setup” object like User.
Solution
Fortunately there is a simple solution: the @future annotation. The @future annotation allows you to create Apex that runs asynchronously at some point in the future (in my tests I’ve found that it runs immediately, or at least very soon after the trigger executes). Methods that use @future are subject to different limits than normal trigger operations because @future methods don’t hold up the trigger (and therefore the entire user experience) while they’re working. Therefore @future methods are often used to perform long-running web service callouts from triggers asynchronously. However, they can also be handy for a case like ours, where we want to update an object that we’re not normally eligible to update.
Calling a method that has been marked as @future is just like calling any other static method. Here’s my trigger, short and sweet:
trigger UpdateContactFromPortalUser on User (after update) { //We only want to run on the single item that the user edited if (Trigger.new.size()==1) { User u = Trigger.new[0]; //And only if it's a portal user if (u.ContactId!=null) { UpdateContactFromPortalUser.updateContacts(u.Id); } } }
Let’s see how that works. In the example given here, I just update a couple of fields from the user record: the name, the email address, and the title.
global class UpdateContactFromPortalUser { @future public static void updateContacts(String userId) { User u = [select ContactId,Email,FirstName,LastName,Title from User where Id=:userId]; if (u!=null && u.ContactId!=null) { Contact c = new Contact(Id=u.ContactId); c.Email = u.Email; c.FirstName=u.FirstName; c.LastName=u.LastName; c.Title=u.Title; update c; }
Source : http://blogs.salesforce.com/support/2009/01/index.html
Recent Comments