Thank you for everyone who participated in the Fix this trigger challenge!
I have much respect to anyone who at least attempted this challenge, regardless of whether or not you succeeded. Remember, resiliency is your #1 skill as a developer!
Here’s the original version that needs to be fixed:
// This lazy dude wrote code to auto-accept and close all cases! trigger LazyEmployee on Case (after insert) { List<Case> newCases = new List<Case>(); for (Case a : Trigger.new) { a.Status = "Closed"; a.Owner = "David Liu"; newCases.add(a) } update newCases; }
And here’s the fixed version:
// This lazy dude wrote code to auto-accept and close all cases! trigger LazyEmployee on Case (before insert) { for (Case newCase : Trigger.new) { newCase.Status = 'Closed'; newCase.OwnerId = '005i0000000OAOO'; } }
This solution is what I consider to be the simplest working trigger. There are many different ways to write the same trigger with the exact same results, so don’t feel too bad even if yours looks drastically different than mine. Also, keep in mind that in most cases it’s better to write code that’s easy to understand, even if it’s not necessarily the most efficient.
All fixes made:
Frequently Asked Questions:
Why didn’t you do a SOQL query for the user ID instead of hard-coding it?
The is a legitimate question because hard-coding is generally bad – things have a habit of changing over time and breaking your hard-code! In this case however, it’s important to note that if you did a SOQL query, you’d still be hard-coding things!
Here’s a sample SOQL query you might use:
[SELECT Id FROM User WHERE FirstName = ‘David’ AND LastName = ‘Liu’];
Notice that using a SOQL query in the above is just as bad as hard-coding the ID instead because:
1. You’re hard-coding the first and last name
2. You might be returned more than one result if another David Liu joins the company (there are many at Google)!
3. A SOQL query takes longer for Salesforce to process than hard-coding the ID, so your Salesforce.com will be slower for users!
Could you have used a Custom Setting to set the Owner ID instead?
Yes, absolutely! Custom settings would make this trigger much more scalable! If the owner ID ever changed in the future, we could simply update our custom setting using point and click, instead of deploying a code change. A+ if you used a custom setting!
Hey. . . you know you could’ve used a workflow rule right?
I sometimes ask questions like these during interviews to make sure the dev has a well-rounded Salesforce understanding! We broke this cardinal rule just this one time, for the sake of learning =)
Why didn’t we first check to see if the values were correct before updating them?
The marginal benefit of checking to see if the values were already “Closed”, for example, aren’t worth the loss in readability. Also, there’s no harm in overriding them with the same value anyway!
Now if this trigger ran on update and we were doing more than just changing a few fields (ie creating new records instead), we’d definitely want to check the previous values of the fields first!
Should we have used Maps?
Not necessary for a simple trigger like this (no SOQL required trigger)! We certainly could have found a use case for them here, but no need introducing any more complexity than is needed!
Why didn’t you use the “one trigger per object” route instead?
I didn’t do this because I cover this topic in Chapter 8, which I haven’t written for you guys yet! Also, while this design pattern is awesome, it’s not totally necessary for smaller orgs that don’t have a lot of existing code running in them.
Hope you guys enjoyed this post – more challenges like these coming soon!
David
the trigger u corrected, will that trigger work fine for bulk operations?
Simply you are awesome !!! David
Great Explanation !!!!
trigger LazyEmployee on Case (before insert) {
List newCases = new List();
User u = [Select ID from User where Name = ‘David Liu’];
for (Case a : Trigger.new) {
a.Status = ‘Closed’;
a.Ownerid = u.ID;
newCases.add(a);
}
update newCases;
}
In the “will it break for 1000’s of records” question above: Isn’t Pranav asking – now you’ve got an “OwnerID = David Liu” trigger, for this user who agreed to accept all cases and close them. What if the script had to run for many distinct users or role-based users (an approver or the account owner? Wouldn’t SOQL have to come in then?
This is a great example to test Apex knowledge. However, the only problem with the solution is hard coding Id (or anything actually). As mentioned above there are many ways to retrieve the Id (i.e. configuration via Custom Settings) and I think the price for retrieval/performance is minimal with regards to maintaining/deploying the code down the road if the hard coded User Id needs to be replaced. If using query and there is more than one user with the same name, then soql should have LIMIT 1. Or the assigned user can be a “configuration” user (by default) instead of current admin/developer user.
I actually think using SOQL in this, and only this case, is more maintenance than hardcoding. A few reasons:
– You have to hard code someone’s name anyway for the SOQL statement.
– What if the person changes their name? Marriage for example!
– If someone else joins with the same name, even if you use LIMIT 1, you still wouldn’t know which of the two to choose.
– If you filter by “Configuration User”, you’re hardcoding again! And what if their profile changes?
User IDs on the other hand never change and users can never be deleted. You basically weight the above vs the chance that a user creates a brand new user for themselves, which can be more or less rare depending on the type of org you work in.
So either scenario works, I think the important thing is understanding what your options are when weighing the two methods. Regardless, this scenario is probably too academic to ever get hurt by either option!
The best, most scalable option is probably the custom setting route you mentioned!
Hi David Sir,
OwnerId is not the Field present in Case.Case who escalate that User become Owner itself.Am i correct sir.
OwnerId is the User who is closing the case =)
Hi Dave! Could you give us an example of when NOT to hard code a trigger?
Seems like hard coding triggers are the way to go, but when and how could this be a bad practice?
Thank you Dave!
A very simple solution.. Just one doubt.. Will it break if someone is inserting thousands of records?
Great question! Since there are no SOQL queries and no DML, it’s bulk safe!