Skip to main content
added 10 characters in body
Source Link
cropredy
  • 73.3k
  • 8
  • 128
  • 284

Because this is a trigger on User (a setup object), you can't do any other DML on non-setup objects in the same transaction. So, you will need to delegate the work to an asynchronous transaction (either future or queueable)

So, your trigger looks like this:

trigger insertTasks on User (after insert) {
   new DelegatedUserSetup().setObjectives(
      [SELECT Id 
        FROM User 
        WHERE Onboarding__c = TRUE AND
              Id IN: Trigger.newMap.keySet() ]); // ensure only current trigger context
} 

and you create another class as an all purpose delegation of user setup that you can use for other use cases.

public class DelegatedUserSetup {
   void setObjectives(User[] users) {
     System.enqueueJob(new SetObjectivesAsQueueable(users));
   } 

public class SetObjectivesAsQueueable implements System.Queueable {
   User[] users; 
   SetObjectivesAsQueueable(User[] users) {this.users = users;}

   public void execute(System.QueueableContext qc) {
       Objectives__c[] masterObjectives = 
         [SELECT Id,Name,Duration__c,Minutes__c,OwnerId,URL__c, Week__c 
           FROM Objectives__c WHERE someField__c = 'MASTER'];

       Objectives__c[] assignedObjectives = new List<Objectives__c>();

       for(User u : this.users){ // every user gets ea masterObjective
         for (Objective__c masterObjective : masterObjectives) {
           assignedObjectives.add(new Objective__c (
              OwnerId = u.Id,  // assign to user
              Name = masterObjective.Name,
              Status__c = 'Not started',
              ... // other fields
              ));
    
         }
       }
       insert assignedObjectives;  // if none, no DML burnt
    }
}
}

Notes

  1. You need some way to differentiate the master objectives from the user-assigned objectives. I put in a placeholder for you
  2. There's a chance you could hit DML limits if the number of users * # master objectives exceeds the number of allowed DML rows per sync transaction
  3. I renamed variables to be more meaningful
  4. I haven't tested the code; there could be typos
  5. You might need to introduce a guard and retry mechanism if the enqueueJob fails

Because this is a trigger on User (a setup object), you can't do any other DML on non-setup objects in the same transaction. So, you will need to delegate the work to an asynchronous transaction (either future or queueable)

So, your trigger looks like this:

trigger insertTasks on User (after insert) {
   new DelegatedUserSetup().setObjectives(
      [SELECT Id 
        FROM User 
        WHERE Onboarding__c = TRUE AND
              Id IN: Trigger.newMap.keySet() ]); // ensure only current trigger context
} 

and you create another class as an all purpose delegation of user setup that you can use for other use cases.

public class DelegatedUserSetup {
   void setObjectives(User[] users) {
     System.enqueueJob(new SetObjectivesAsQueueable(users)); 

public class SetObjectivesAsQueueable implements System.Queueable {
   User[] users; 
   SetObjectivesAsQueueable(User[] users) {this.users = users;}

   public void execute(System.QueueableContext qc) {
       Objectives__c[] masterObjectives = 
         [SELECT Id,Name,Duration__c,Minutes__c,OwnerId,URL__c, Week__c 
           FROM Objectives__c WHERE someField__c = 'MASTER'];

       Objectives__c[] assignedObjectives = new List<Objectives__c>();

       for(User u : this.users){ // every user gets ea masterObjective
         for (Objective__c masterObjective : masterObjectives) {
           assignedObjectives.add(new Objective__c (
              OwnerId = u.Id,  // assign to user
              Name = masterObjective.Name,
              Status__c = 'Not started',
              ... // other fields
              ));
    
         }
       }
       insert assignedObjectives;  // if none, no DML burnt
    }
}
}

Notes

  1. You need some way to differentiate the master objectives from the user-assigned objectives. I put in a placeholder for you
  2. There's a chance you could hit DML limits if the number of users * # master objectives exceeds the number of allowed DML rows per sync transaction
  3. I renamed variables to be more meaningful
  4. I haven't tested the code; there could be typos
  5. You might need to introduce a guard and retry mechanism if the enqueueJob fails

Because this is a trigger on User (a setup object), you can't do any other DML on non-setup objects in the same transaction. So, you will need to delegate the work to an asynchronous transaction (either future or queueable)

So, your trigger looks like this:

trigger insertTasks on User (after insert) {
   new DelegatedUserSetup().setObjectives(
      [SELECT Id 
        FROM User 
        WHERE Onboarding__c = TRUE AND
              Id IN: Trigger.newMap.keySet() ]); // ensure only current trigger context
} 

and you create another class as an all purpose delegation of user setup that you can use for other use cases.

public class DelegatedUserSetup {
   void setObjectives(User[] users) {
     System.enqueueJob(new SetObjectivesAsQueueable(users));
   } 

public class SetObjectivesAsQueueable implements System.Queueable {
   User[] users; 
   SetObjectivesAsQueueable(User[] users) {this.users = users;}

   public void execute(System.QueueableContext qc) {
       Objectives__c[] masterObjectives = 
         [SELECT Id,Name,Duration__c,Minutes__c,OwnerId,URL__c, Week__c 
           FROM Objectives__c WHERE someField__c = 'MASTER'];

       Objectives__c[] assignedObjectives = new List<Objectives__c>();

       for(User u : this.users){ // every user gets ea masterObjective
         for (Objective__c masterObjective : masterObjectives) {
           assignedObjectives.add(new Objective__c (
              OwnerId = u.Id,  // assign to user
              Name = masterObjective.Name,
              Status__c = 'Not started',
              ... // other fields
              ));
    
         }
       }
       insert assignedObjectives;  // if none, no DML burnt
    }
}
}

Notes

  1. You need some way to differentiate the master objectives from the user-assigned objectives. I put in a placeholder for you
  2. There's a chance you could hit DML limits if the number of users * # master objectives exceeds the number of allowed DML rows per sync transaction
  3. I renamed variables to be more meaningful
  4. I haven't tested the code; there could be typos
  5. You might need to introduce a guard and retry mechanism if the enqueueJob fails
added 7 characters in body
Source Link
cropredy
  • 73.3k
  • 8
  • 128
  • 284

Because this is a trigger on User (a setup object), you can't do any other DML on non-setup objects in the same transaction. So, you will need to delegate the work to an asynchronous transaction (either future or queueable)

So, your trigger looks like this:

trigger insertTasks on User (after insert) {
   new DelegatedUserSetup().setObjectives(
      [SELECT Id 
        FROM User 
        WHERE Onboarding__c = TRUE AND
              Id IN: Trigger.newMap.keySet() ]); // ensure only current trigger context
} 

and you create another class as an all purpose delegation of user setup that you can use for other use cases.

public class DelegatedUserSetup {
   void setObjectives(User[] users) {
     System.enqueueJob(new SetObjectivesAsQueueable(users)); 

public class SetObjectivesAsQueueable implements System.Queueable {
   User[] users; 
   SetObjectivesAsQueueable(User[] users) {this.users = users;}

   public void execute(System.QueueableContext qc) {
       Objectives__c[] masterObjectives = 
         [SELECT Id,Name,Duration__c,Minutes__c,OwnerId,URL__c, Week__c 
           FROM Objectives__c WHERE someField__c = 'MASTER'];

       Objectives__c[] assignedObjectives = new List<Objectives__c>();

       for(User u : this.users){ // every user gets ea masterObjective
         for (Objective__c masterObjective : masterObjectives) {
           assignedObjectives.add(new Objective__c (
              OwnerId = u.Id,  // assign to user
              Name = masterObjective.Name,
              Status__c = 'Not started',
              ... // other fields
              ));
    
         }
       }
       insert assignedObjectives;  // if none, no DML burnt
    }
}
}

Notes

  1. You need some way to differentiate the master objectives from the user-assigned objectives. I put in a placeholder for you
  2. There's a chance you could hit DML limits if the number of users * # master objectives exceeds the number of allowed DML rows per sync transaction
  3. I renamed variables to be more meaningful
  4. I haven't tested the code; there could be typos
  5. You might need to introduce a guard and retry mechanism if the enqueueJob fails

Because this is a trigger on User (a setup object), you can't do any other DML on non-setup objects in the same transaction. So, you will need to delegate the work to an asynchronous transaction (either future or queueable)

So, your trigger looks like this:

trigger insertTasks on User (after insert) {
   new DelegatedUserSetup().setObjectives(
      [SELECT Id 
        FROM User 
        WHERE Onboarding__c = TRUE AND
              Id IN: Trigger.newMap.keySet() ]); // ensure only current trigger context
} 

and you create another class as an all purpose delegation of user setup that you can use for other use cases.

public class DelegatedUserSetup {
   void setObjectives(User[] users) {
     System.enqueueJob(new SetObjectivesAsQueueable(users)); 

public class SetObjectivesAsQueueable implements System.Queueable {
   User[] users; 
   SetObjectivesAsQueueable(User[] users) {this.users = users;}

   void execute(System.QueueableContext qc) {
       Objectives__c[] masterObjectives = 
         [SELECT Id,Name,Duration__c,Minutes__c,OwnerId,URL__c, Week__c 
           FROM Objectives__c WHERE someField__c = 'MASTER'];

       Objectives__c[] assignedObjectives = new List<Objectives__c>();

       for(User u : this.users){ // every user gets ea masterObjective
         for (Objective__c masterObjective : masterObjectives) {
           assignedObjectives.add(new Objective__c (
              OwnerId = u.Id,  // assign to user
              Name = masterObjective.Name,
              Status__c = 'Not started',
              ... // other fields
              ));
    
         }
       }
       insert assignedObjectives;  // if none, no DML burnt
    }
}
}

Notes

  1. You need some way to differentiate the master objectives from the user-assigned objectives. I put in a placeholder for you
  2. There's a chance you could hit DML limits if the number of users * # master objectives exceeds the number of allowed DML rows per sync transaction
  3. I renamed variables to be more meaningful
  4. I haven't tested the code; there could be typos
  5. You might need to introduce a guard and retry mechanism if the enqueueJob fails

Because this is a trigger on User (a setup object), you can't do any other DML on non-setup objects in the same transaction. So, you will need to delegate the work to an asynchronous transaction (either future or queueable)

So, your trigger looks like this:

trigger insertTasks on User (after insert) {
   new DelegatedUserSetup().setObjectives(
      [SELECT Id 
        FROM User 
        WHERE Onboarding__c = TRUE AND
              Id IN: Trigger.newMap.keySet() ]); // ensure only current trigger context
} 

and you create another class as an all purpose delegation of user setup that you can use for other use cases.

public class DelegatedUserSetup {
   void setObjectives(User[] users) {
     System.enqueueJob(new SetObjectivesAsQueueable(users)); 

public class SetObjectivesAsQueueable implements System.Queueable {
   User[] users; 
   SetObjectivesAsQueueable(User[] users) {this.users = users;}

   public void execute(System.QueueableContext qc) {
       Objectives__c[] masterObjectives = 
         [SELECT Id,Name,Duration__c,Minutes__c,OwnerId,URL__c, Week__c 
           FROM Objectives__c WHERE someField__c = 'MASTER'];

       Objectives__c[] assignedObjectives = new List<Objectives__c>();

       for(User u : this.users){ // every user gets ea masterObjective
         for (Objective__c masterObjective : masterObjectives) {
           assignedObjectives.add(new Objective__c (
              OwnerId = u.Id,  // assign to user
              Name = masterObjective.Name,
              Status__c = 'Not started',
              ... // other fields
              ));
    
         }
       }
       insert assignedObjectives;  // if none, no DML burnt
    }
}
}

Notes

  1. You need some way to differentiate the master objectives from the user-assigned objectives. I put in a placeholder for you
  2. There's a chance you could hit DML limits if the number of users * # master objectives exceeds the number of allowed DML rows per sync transaction
  3. I renamed variables to be more meaningful
  4. I haven't tested the code; there could be typos
  5. You might need to introduce a guard and retry mechanism if the enqueueJob fails
Source Link
cropredy
  • 73.3k
  • 8
  • 128
  • 284

Because this is a trigger on User (a setup object), you can't do any other DML on non-setup objects in the same transaction. So, you will need to delegate the work to an asynchronous transaction (either future or queueable)

So, your trigger looks like this:

trigger insertTasks on User (after insert) {
   new DelegatedUserSetup().setObjectives(
      [SELECT Id 
        FROM User 
        WHERE Onboarding__c = TRUE AND
              Id IN: Trigger.newMap.keySet() ]); // ensure only current trigger context
} 

and you create another class as an all purpose delegation of user setup that you can use for other use cases.

public class DelegatedUserSetup {
   void setObjectives(User[] users) {
     System.enqueueJob(new SetObjectivesAsQueueable(users)); 

public class SetObjectivesAsQueueable implements System.Queueable {
   User[] users; 
   SetObjectivesAsQueueable(User[] users) {this.users = users;}

   void execute(System.QueueableContext qc) {
       Objectives__c[] masterObjectives = 
         [SELECT Id,Name,Duration__c,Minutes__c,OwnerId,URL__c, Week__c 
           FROM Objectives__c WHERE someField__c = 'MASTER'];

       Objectives__c[] assignedObjectives = new List<Objectives__c>();

       for(User u : this.users){ // every user gets ea masterObjective
         for (Objective__c masterObjective : masterObjectives) {
           assignedObjectives.add(new Objective__c (
              OwnerId = u.Id,  // assign to user
              Name = masterObjective.Name,
              Status__c = 'Not started',
              ... // other fields
              ));
    
         }
       }
       insert assignedObjectives;  // if none, no DML burnt
    }
}
}

Notes

  1. You need some way to differentiate the master objectives from the user-assigned objectives. I put in a placeholder for you
  2. There's a chance you could hit DML limits if the number of users * # master objectives exceeds the number of allowed DML rows per sync transaction
  3. I renamed variables to be more meaningful
  4. I haven't tested the code; there could be typos
  5. You might need to introduce a guard and retry mechanism if the enqueueJob fails