2

I have a 'Before Insert' trigger that was developed only because of the 'clone' functionality in SF.

In our Managed Package if someone clones our custom object there are a number of fields that we do NOT want to just be cloned over to the new record.

That trigger works fine and it meets the objective of clearing those fields on creation of an object via cloning.

But now we are finding the need to allow those SAME fields to be loaded into the application via 'Load Custom Objects'. As you can imagine the 'Before Insert' trigger isn't stopping the loading of the objects in any way but it is making sure those objects have the certain set of fields blanked out.

I have actually solved the problem but I am not a fan of the solution. I have added a field to the custom object called 'Bypass New Trigger' that defaults to null and then in my trigger I only blank out the fields if 'Bypass New Trigger' is null. In my load files I set that new field to be anything but null and they load fine with all data intact.

Seems a little kludgy if you ask me.

Is there syntax that can be used in a "Before Insert" trigger that would let me know the source of the record being inserted? Something like IsCloned() or IsDataLoad() ??

Thanks in advance for any assistance you can provide.

  • Thanks for the answers folks! I actually like the idea that SFDC should add this as standard features - reading the 'idea' above it actually sounds like others have even more compelling needs than we do... but at least now I know how to work around this problem properly! – AngiB Nov 14 '12 at 16:52
5

Triggers are data centric, they are not aware of the processes around them and nor should they be, it would lead to to much strange behaviour in different contexts and confusion for end users. For example, what about use of the Salesforce API's for example, same problem. So couple of options...

  1. Action Override for Clone. What you have here, is basically a client process requirement your trying to deal with at the database level. Which is causing some design side effects. Though in fairness we often consider these routes, due to the fact that there is no 'process' entry point to the client logic in Salesforce. While not 100% bullet proof (for example SObject.clone), you can in fact get close enough via an override of the Clone action on your Custom Object under the 'Standard Buttons and Links' section. This way you could implement a VF page to display just what you need and override the StandardController save method to clear the fields you don't. Leaving all other contexts intact and no need for the trigger, leaving your Data Loading experience as expected.

  2. Control Field. is to continue with the route you have taken, that in my view is also not so bad. The trick to making it feel better is the naming and meaning of the field, ideally something users and devs will relate to in relation to the other fields it effects. So called 'control fields' serve only to adjust the behaviour of triggers. These typically default (via the field definition) to the most commonly desired behaviour. Thus in the majority of use cases (UI, API's etc) where your records are created or updated, they need not be considered by the user or developer. It is also good practice user experience wise (if your use case allows it) to throw validation errors if the trigger logic senses fields with values set or contain certain values that disagree with the 'control' fields indicated behaviour.

If you go for 2, I would invert the meaning of your control field, e.g. 'Clear None Cloneable Fields'. Default it to False in the field definition. From a UI perspective place it in a section with the fields it effects near the top (or hide it as you wish). In your trigger, if it's false, then flip it during the on before insert, so that it becomes set to true by the time the record is eventually saved. Later as users attempt to Clone records created this way, it will be carried forward and fire your logic.

Tricky stuff though to design, general rule of thumb is know and test all your use cases, typically all the UI actions / operations and CRUD combinations (you don't have to test multiple SF API routes here, Data Loader or even DML in tests will do). Enjoy!

P.S. If you want to try 1 and need an example let me know, I'll update answer.

| improve this answer | |
  • Andrew, your Control Field answer has spurred me to a follow-up pro-con discussion over here. Would love to hear your thoughts on it. – twamley Nov 14 '12 at 19:23
  • Hmmm sure, let me take a look.... :) – Andrew Fawcett Nov 14 '12 at 19:45
1

Another commonly used approach is a User level flag because in most organisations, data loads are the remit of certain fixed users.

So you could add a Bypass Trigger custom field to the User, which is set to true only for the Data load user, to allow it to load in the fields, whilst the trigger continues to blank out the not to be cloned fields for the other users.

This is also more extensible in that you could add the check for Bypass Triggers as boiler plate in your triggers so that all you need to do if there is a need to bypass trigger logic for a data load, is to set the flag on the Data load user.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.