2011-09-15 16 views
36

Sto tentando di inviare più email in base a un valore booleano nel mio database. L'app è una semplice app di pianificazione e l'utente può contrassegnare il proprio turno come "sostituto_need" e questo dovrebbe inviare email a tutti gli utenti che hanno richiesto di ricevere queste e-mail. Il problema è che sembra che solo tutti sembrano inviare a una sola email. Ecco il mio codice corrente:Invia a più destinatari in Rails con ActionMailer

def request_replacement(shift) 
     @shift = shift 
     @user = shift.user 
     @recipients = User.where(:replacement_emails => true).all 
     @url = root_url 
     @recipients.each do |r| 
     @name = r.fname 
     mail(:to => r.email, 
      :subject => "A replacement clerk has been requested") 
     end 
    end 
+7

La chiamata a #mail in realtà non invia l'email, crea solo l'oggetto di posta. La chiamata di #deliver su quell'oggetto di posta lo invia. Quindi, solo l'ultimo creato viene inviato quando si chiama #deliver (presumibilmente in un altro bit di codice). –

risposta

51

sto avendo lo stesso problema .. so cosa l'affare è .. Ho eludere facendo:

invece di chiamare

Mailer.request_replacement(shift).deliver 

dal mio controllo,

I 'Definire un metodo di classe sul mailer e chiamarlo.Questo metodo dovrebbe quindi scorrere l'elenco e chiamare consegnare "n" volte ... che sembra funzionare

class Mailer 

    def self.send_replacement_request(shift) 
    @recipients = ... 
    @recipients.each do |recipient| 
     request_replacement(recipient, shift).deliver 
    end 
    end 

    def request_replacement(recipient, shift) 
    ... 
    mail(...) 
    end 
end 
.210

e dal controller, chiamare

Mailer.send_replacement_request(shift) 
+1

Non credo che l'avrei mai capito. Grazie! – turboladen

+1

soluzione impressionante! –

+0

Se non si chiama il metodo di consegna nel controller, esso non entra nemmeno nel metodo mailer. – kamal

65

Può semplicemente inviare una e-mail per più destinatari come questo.

def request_replacement(shift) 
    @shift = shift 
    @user = shift.user 
    @recipients = User.where(:replacement_emails => true) 
    @url = root_url 
    emails = @recipients.collect(&:email).join(",") 
    mail(:to => emails, :subject => "A replacement clerk has been requested") 
end 

Questo richiederà tutte le vostre @recipients indirizzi e-mail e unirsi a loro con ,. Penso che si possa anche passare un array alla chiave :to ma non si è sicuri.

L'unico problema è che non sarà possibile utilizzare @name nel modello. :(

+9

Sì, ma davvero non voglio esporre gli indirizzi email di ogni utente ... Penso di aver trovato una soluzione spostando il blocco .each nel modello e chiamando la consegna da lì. – Slick23

+10

Vero, se è il caso. Puoi usare il campo 'bcc'. –

+1

FWIW, questo non sembra funzionare su Amazon SES, dove si aspettano virgole come delimitatori (anche se funziona quando si utilizza la virgola anziché il punto e virgola). –

7

Per evitare che ogni destinatario di vedere gli altri indirizzi di posta elettronica:

@recipients.each{ |recipient| Mailer.request_replacement(recipient, shift).deliver } 
+0

Puoi anche aggiungerli come 'bcc', come segue:' mail (: to => "[email protected]",: subject => "È stato richiesto un commesso sostitutivo",: bcc => @ recipients.map (&: email) .join (",")) ' – cgenco

+0

Voglio solo sottolineare che il' join' nel tuo commento non è necessario. il mailer d'azione può prendere matrici di email – TheRealMrCrowley

0

sto usando Rails 5 e ho la stessa situazione, l'email è stata inviata solo per l'ultimo destinatario, ma anche è stato inviato come testo normale non come Email HTML

Dopo aver provato alcuni consigli, ho finito per fissarlo in questo modo:

Il programma di posta:

class BrochureMailer < ApplicationMailer 
    default from: "[email protected]" 

    def newsletter(sponsor, brochures_list) 
     @sponsor = sponsor 
     @brochures = brochures_list 

     mail(
      to: @sponsor.email, 
      subject: "Interesting subject!" 
     ) 
    end 
end 

Il controller in cui viene richiamato il programma di posta:

class Admin::DashboardController < Admin::BaseController 
    def send_newsletter 
     sponsors = params[:sponsor_ids] 
     brochures = params[:brochure_ids] 

     sponsors = Sponsor.where(id: sponsors) 
     brochures = Brochure.where(id: brochures).to_a 

     # Send Newsletter email to the given Sponsors 
     sponsors.each do |sponsor| 
      BrochureMailer.newsletter(sponsor, brochures).deliver_later 
     end 

     redirect_back(fallback_location: admin_root_path, success: 'Newsletter sent!') 
    end 
end 

E nella vista, qualcosa di simile:

<% @brochures.each do |brochure| %> 
    <table width="280" border="0" cellpadding="0" cellspacing="0" align="left" valign="top" class="floater"> 
     <tr> 
      <td align="center" valign="top"> 
       <a target="_blank" href="<%= brochure_url(brochure) %>"> 
        <img border="0" vspace="0" hspace="0" src="<%= brochure.image.blank? ? 'default.png' : brochure.image.url(public: true) %>" width="250" height="142"> 
        <b><%= brochure.title %></b> 
       </a> 
       <br> 
       <%= brochure.description.truncate(60) %> 
      </td> 
     </tr> 
    </table> 
<% end %> 

E funziona come un fascino! Non sono sicuro se questo è il modo corretto o il modo migliore per andare, ma consideralo come una seconda possibilità.

Spero possa essere utile per qualcun altro.

Problemi correlati