2013-12-19 6 views
1

у меня есть класс мэйлера как этотзадержку ActionMailer не может доставить несколько получателей

class Mailer < ActionMailer::Base 
    def newsletter_scheduler() 
    recipients = User.all.to_a 
    Mailer.delay_for(certain_time.days).newsletter(recipients) 
    end 

    def newsletter(recipients) 
    recipients.each do |user| 
     Logger.log("sending newsletter to #{user.email}" 
     mail(
     to: user.email, 
     subject: "What's hot last week", 
    ).deliver 
    end 
end 

Я не ищу альтернативы для реализации этого ... проблемы заключается в том, что это отправляет бюллетень последнего получатель только и несколько раз Так, например, в specs

it 'sends newsletter to all users' do 
    Mailer.newsletter_scheduler() 
    newsletters = ActionMailer::Base.deliveries 

    newsletters.each { |nl| p nl.to } 
end 

я получаю это (примечание: у меня есть 5 пользователей)

["[email protected]"] 
["[email protected]"] 
["[email protected]"] 
["[email protected]"] 
["[email protected]"] 

может кто-нибудь сказать мне, почему это происходит в то время как регистратор показывает следующий

sending newsletter to [email protected] 
sending newsletter to [email protected] 
sending newsletter to [email protected] 
sending newsletter to [email protected] 
sending newsletter to [email protected] 

[EDIT] следующий код имеет тот же эффект, что и код выше

class Newsletter 
    def self.schedule 
    recipients = User.all.map { |u| u.id } 
    Mailer.delay_for(certain_time.days).newsletter(recipients) 
    end 
end 

class Mailer < ActionMailer::Base 
    def newsletter(recipients) 
    recipients.each do |id| 
     user = User.find(id) 
     Logger.log("sending newsletter to #{user.email}" 
     mail(
     to: user.email, 
     subject: "What's hot last week", 
    ) 
    end 
end 

Newsletter.schedule() #produces the same results in the specs 

ответ

2

Ваш код тоже данный другой выпуск. Ожидается, что #deliver будет вызван вне действия почты, как я показал вам в моем коде выше.

Рассмотрим разделить ваш код

class NewsletterScheduler 
    def self.execute 
    User.all.each do |user| 
     Mailer.delay_for(certain_time.days).newsletter(user) 
    end 
    end 
end 

class Mailer < ActionMailer::Base 
    def newsletter(user) 
    Logger.log("sending newsletter to #{user.email}" 
    mail(to: user.email, subject: "What's hot last week") 
    end 
end 

NewsletterScheduler.execute 

Важное предупреждение: Вы никогда не должны пройти сложный объект в качестве аргументов в очереди. Вместо этого всегда передавайте ссылку.

В вашем случае изменение

def newsletter(recipients) 

для принимает массив идентификаторов вместо массива объектов пользователя. Причина в том, что объекты сложны, и внутреннее состояние может измениться, особенно если они хранятся в базе данных. Более того, сериализация примитивного значения более эффективна, чем сериализация сложного объекта.

class NewsletterScheduler 
    def self.execute 
    User.all.each do |user| 
     Mailer.delay_for(certain_time.days).newsletter(user_id) 
    end 
    end 
end 

class Mailer < ActionMailer::Base 
    def newsletter(user_id) 
    user = User.find(user_id) 
    Logger.log("sending newsletter to #{user.email}" 
    mail(to: user.email, subject: "What's hot last week") 
    end 
end 
+0

это не работает ... без доставки в почтовые отправления не отправляется ... и с доставкой происходит такое же поведение, как описано выше. –

+0

Он не может иметь такое же поведение, если вы правильно извлекли код, как я показал. Пожалуйста, обновите свой обновленный код или обновите существующий ответ. –

+0

обновил вопрос –

Смежные вопросы