1

We use MailChimp Salesforce App. Only thing that sucks about this app is that it creates records that are populating our database. I manually export records and do a delete through Jitterbit or other forms of dataloader.. I am trying to write an Apex trigger that auto deletes the record as MailChimp app creates records. Is this a safe way to do it? Or are there any better ways?

trigger MCSubscriberActivityDelete on MC4SF__MC_Subscriber_Activity__c (before insert) {

    for(MC4SF__MC_Subscriber_Activity__c mca : Trigger.new){
        if(mca.IsDeleted != true){
            List<MC4SF__MC_Subscriber_Activity__c> mcad = [SELECT Id, IsDeleted
                                                            FROM MC4SF__MC_Subscriber_Activity__c
                                                            WHERE IsDeleted = false];
            delete mcad;
        }

    }// for loop

}

4 Answers 4

4

Just for the reference, the code in your original question comes with several problems. This is not to nag on your code, but rather to allow you understand how to improve it.

  1. You try to select records, that are not yet committed to the database
  2. You want to delete records that were inserted in the same context as the delete
  3. You are issuing SOQL and DML Queries inside a loop

Fixing 1 is easy - change the before insert to after insert.

The 2nd one is a little tricky, because for this to work you need an @future annotated method in another class (as crop1645 correctly pointed out). Therefore, create an apex class that exposes a single method like this:

public class TriggerHelper {
    @future
    public static void deleteRecords(Set<Id> objectsIdsToDelete) {
        delete [Select Id from MC4SF__MC_Subscriber_Activity__c where Id in : objectsIdsToDelete];
    }
}

Then call this static method from your code. The 3rd one is also an easy one to fix: First, collect a set of ids to delete, then process them in one step. This is done in the deleteRecords-Method, so no need to worry about this again.

Finally, your code should look somewhat like this:

trigger MCSubscriberActivityDelete on MC4SF__MC_Subscriber_Activity__c (after insert) {
    TriggerHelper. deleteRecords(Trigger.newMap.keySet());
}

This is of course not the best way, if (and you'd have to try that for yourself) the Mailchimp doesn't mind the errors caused by a validation rule. This would actually save you from keeping unwanted records in your recycle bin for several days and would be a much cleaner solution to the problem.

2
  • Thanks, this was exactly kind of help I was looking for. I have to read about @feature method. I am pretty new to Apex. Sep 12, 2014 at 0:20
  • If you wait until Winter15 goes live there's something quite similar to @future in the new Queueable interface that IMO is much better. Sep 12, 2014 at 6:01
3

I would assume (but may be wrong) that the records are inserted for a purpose and not inserting them or deleting them quickly might break the overall process.

If that is the case, instead of a trigger you can write a class that implements Schedulable and use the "Schedule Apex" button to run that code once a day (or multiple times a day if there are more than 10,000 records a day):

public class MailChimpCleanupSchedulable implements Schedulable {
    public void execute(SchedulableContext context) {
        delete [
                SELECT Id
                FROM MC4SF__MC_Subscriber_Activity__c
                WHERE CreatedDate = YESTERDAY
                LIMIT 10000
                ];
    }
}

Deleted records will consume space (as they can be restored via the recycle bin) until they are automatically permanently deleted after 15 days. If you need to recover the space more aggressively, you can also call one of the Database.emptyRecycleBin methods.

2
  • This is so smart. I will try this option as well. Sep 12, 2014 at 0:22
  • If you use "WHERE CreatedDate <= YESTERDAY", you can try to catch up with records that exceeded the 10000 DML limit on days that are less busy. Oct 4, 2017 at 16:00
1

If you're really just trying to prevent the insertion of those records, you can just throw an error on the insert:

trigger MCSubscriberActivityDelete on MC4SF__MC_Subscriber_Activity__c (before insert) {

     for(MC4SF__MC_Subscriber_Activity__c mca : Trigger.new) {
           mca.addError();
     }

} // for loop

The only thing to be careful of here is that the insertion of those records isn't some step in a larger transaction. The act of adding the error will roll back the entire transaction. It's also possible that MailChimp will attempt to continue to try and insert those record if it doesn't find them, although knowing a bit about their integration, I doubt that.

A simpler, no code solution would be a validation rule that always fails on the MC4SF__MC_Subscriber_Activity__c object.

3
  • 1
    or, in an after insert trigger, do a @future that deletes the records
    – cropredy
    Sep 11, 2014 at 22:32
  • Thanks Greenstork! I will try the validation rule— but how would you write the validation rule that to make it fail? Sep 11, 2014 at 22:50
  • Validation error conditions just return a boolean, which you can do yourself. Just put true in your Error Condition Formula and it will always throw an error.
    – greenstork
    Sep 11, 2014 at 23:18
0

Looks like you're trying to delete the MC Subscriber activity, there's actually a built-in feature on the MailChimp for Salesforce app that allows you to select how long Subscriber Activity will be kept:

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .