2010-09-17 21 views
1

J'ai un delayed_job conçu pour envoyer un email en utilisant un mailer.Comment enregistrer un objet uniquement après la fin d'un job retardé?

À la fin, je dois enregistrer que le courriel a été envoyé - je fais ceci en sauvant le ContactEmail nouvellement créé.

En ce moment, les nouveaux enregistrements de CONTACTEMAIL est enregistré même si le delayed_job échoue.

Comment puis-je corriger cela pour que la nouvelle ContactEmail n'est enregistrée lorsque le logiciel de messagerie est envoyé avec succès?

Voici l'extrait de la tâche cron qui appelle la delayed_job:

puts contact_email.subject 

    contact_email.date_sent = Date.today 
    contact_email.date_created = Date.today 

    contact_email.body = email.substituted_message(contact, contact.colleagues) 

    contact_email.status = "sent" 

    #Delayed::Job.enqueue OutboundMailer.deliver_campaign_email(contact,contact_email) 
    Delayed::Job.enqueue SomeMailJob.new(contact,contact_email) 

    contact_email.save #now save the record 

Voici le some_mail_job.rb

class SomeMailJob < Struct.new(:contact, :contact_email) 
    def perform 
    OutboundMailer.deliver_campaign_email(contact,contact_email) 
    end 
end 

Et voici le outbound_mailer:

class OutboundMailer < Postage::Mailer 

    def campaign_email(contact,email) 
    subject email.subject 
    recipients contact.email 
    from  '<[email protected]>' 
    sent_on Date.today 

    body  :email => email 
    end 

Répondre

-1
  1. Vous avez besoin de sy la livraison nchronique arrêtez donc d'utiliser le travail retardé dans ce cas et faites la distribution standard de courrier.
  2. ou ajouter success colonne pour vous ContactEmail - enregistrer avec initialement false puis mettre à jour dans l'emploi à true
+0

donc l'enregistrer avant d'exécuter le delayed_job (il doit être un delayed_job je le suis en cours d'exécution en heroku) --- L'instance est-elle persistante dans le travail retardé? – Angela

+0

Je ne savais pas que vous êtes lié à delayed_job par heroku. Comme vous avez déjà une colonne d'état, mettez juste à jour l'état dans le travail ou sauvegardez le nouvel enregistrement dans le travail au lieu de la tâche cron. – gertas

0

Vous pouvez mettre à jour le statut dans l'emploi de l'effectuer lui-même.

Par exemple, quelque chose comme:

contact_email.status = 'queued' 
contact_email.save 
contact_email.delay.deliver_campaign_email 

Et puis dans votre ContactEmail classe, quelque chose à l'effet de

def deliver_campaign_email 
    OutboundMailer.deliver_campaign_email(self.contact, self) 
    self.status = 'sent' # or handle failure and set it appropriately 
    self.save 
end 

delayed_job a quelques morceaux magiques qui ajoute à vos modèles qui traiteront avec la persistance.

Afin de traiter votre OutboundMailer lancer une exception, vous pouvez faire quelque chose comme ceci:

def deliver_campaign_email 
    begin 
    OutboundMailer.deliver_campaign_email(self.contact, self) 
    self.status = 'sent' 
    rescue 
    self.status = 'failed' # or better yet grab the the message from the exception 
    end 
    self.save 
end 
+0

Je vois ... quand je fais contact_email.save - qui crée le « dossier » qui signifie qu'il a été sauvé avec succès ... donc je ne peux pas vraiment le mettre avant de livrer le courrier électronique ..... si je supprimé que ligne de la méthode d'exécution (qui est ce que je suppose que vous voulez dire?) Est-ce que cela fonctionnerait sur l'achèvement réussi? Que se passe-t-il si l'OutboundMailer échoue? – Angela

+0

échec OutboundMailer soulève exception arrête l'invocation de la méthode ainsi sans traitement d'autres déclarations – gertas

+0

Vous devez sauver l'exception. –