2011-09-15 28 views
36

Tôi đang cố gắng gửi nhiều email dựa trên giá trị boolean trong cơ sở dữ liệu của mình. Ứng dụng này là một ứng dụng lập lịch đơn giản và người dùng có thể đánh dấu sự thay đổi của họ là "replace_needed" và điều này sẽ gửi email cho tất cả người dùng đã yêu cầu nhận những email này. Rắc rối là, nó chỉ có vẻ như gửi đến một email. Đây là mã hiện tại của tôi:Gửi cho nhiều người nhận trong Rails với 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

Cuộc gọi tới #mail không thực sự gửi email, nó chỉ tạo đối tượng thư. Gọi #deliver trên đối tượng thư đó sẽ gửi nó. Do đó, chỉ lần tạo cuối cùng được gửi khi bạn gọi #deliver (có lẽ trong một bit mã khác). –

Trả lời

51

tôi đang gặp vấn đề này cùng .. dunno những gì thỏa thuận này được .. Tôi tránh né nó bằng cách:

thay vì gọi

Mailer.request_replacement(shift).deliver 

từ bộ điều khiển của tôi,

tôi 'd xác định một phương thức lớp trên bưu phẩm, và gọi đó. Phương pháp đó sau đó sẽ lặp qua danh sách và gọi phân phối "n" lần ... có vẻ như hoạt động

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

và từ bộ điều khiển, gọi

Mailer.send_replacement_request(shift) 
+1

Tôi không nghĩ rằng tôi đã từng nghĩ ra điều đó. Cảm ơn bạn! – turboladen

+1

giải pháp tuyệt vời! –

+0

Nếu bạn không gọi phương thức phân phối trong bộ điều khiển, nó thậm chí không đi vào bên trong phương thức gửi thư. – kamal

65

Bạn chỉ có thể gửi một email cho nhiều người nhận như thế này.

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 

Điều này sẽ lấy tất cả địa chỉ email @recipients của bạn và tham gia với ,. Tôi nghĩ bạn cũng có thể chuyển một mảng tới khóa :to nhưng không chắc chắn.

Vấn đề duy nhất là bạn sẽ không thể sử dụng @name trong mẫu của mình. :(

+9

Vâng, nhưng tôi thực sự không muốn để lộ các địa chỉ email của mỗi người dùng ... Tôi nghĩ rằng tôi đã tìm thấy một giải pháp bằng cách di chuyển khối .each vào mô hình và gọi điện từ đó. – Slick23

+10

Đúng, nếu đúng như vậy. Bạn có thể sử dụng trường 'bcc'. –

+1

FWIW, điều này dường như không hoạt động trên Amazon SES, nơi họ đang mong đợi dấu phẩy là dấu phân cách (mặc dù nó hoạt động khi bạn sử dụng dấu phẩy thay vì dấu chấm phẩy). –

7

Để ngăn chặn mỗi người nhận từ nhìn thấy những địa chỉ email khác:

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

Bạn cũng có thể thêm chúng dưới dạng 'bcc', như sau:' mail (: to => "[email protected]",: subject => "Thư ký thay thế đã được yêu cầu",: bcc => @ recipient.map (&: email) .join (",")) ' – cgenco

+0

Tôi chỉ muốn chỉ ra rằng' tham gia' trong bình luận của bạn là không cần thiết. mailer hành động có thể lấy mảng email – TheRealMrCrowley

0

Tôi đang sử dụng Rails 5 và tôi có tình huống tương tự, email được gửi chỉ cho người nhận cuối cùng nhưng cũng có thể nó đã được gửi cũng giống như văn bản đơn giản không phải là Email HTML.

Sau khi thử một số lời khuyên, tôi đã kết thúc sửa chữa nó theo cách này:

Bưu phẩm:

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 

Bộ điều khiển nơi bưu phẩm được gọi:

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 

Và trong chế độ xem, một cái gì đó như thế này:

<% @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 %> 

Và nó hoạt động như một sự quyến rũ! Tôi không chắc chắn nếu đây là cách chính xác hoặc cách tối ưu nhất để đi nhưng chỉ xem xét nó như là một khả năng thứ hai.

Tôi hy vọng nó có thể hữu ích cho người khác.

Các vấn đề liên quan