ActionMailer рендерит один раз, отправлять много раз? - PullRequest
4 голосов
/ 25 июня 2011

Я пытаюсь выяснить, возможно ли использовать ActionMailer без Rails, чтобы визуализировать представление html.erb один раз, а затем отправить его несколько раз, просто используя разные электронные письма в: to?

ПРИМЕЧАНИЕ: я НЕ использую полный стек Rails, просто ActionMailer

Так в классе почтовика

class MyMailer < ActionMailer::Base
  default :from     => 'johndoe@example.com',
          :subject  => 'New Arrivals!'

  def new_products(customer, new_products)
    @new_products = new_products

    mail :to => customer.email do |format|
        format.html
    end
  end
end

Затем в коде клиента нам нужно получить новые продукты и клиентов.

products = Product.new_since_yesterday
customers = Customer.all

customers.each do |c|
  MyMailer.new_products(c, products).deliver
end

Допустим, это отправляется один раз в день, поэтому мы хотим получать новые продукты только с момента последней отправки электронного письма. Мы хотим сделать это только один раз, так как новые продукты на сегодняшний день не будут меняться между электронными письмами. Насколько я знаю, это будет вызывать render каждый раз, когда электронное письмо создается и отправляется.

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

Очевидно, что для большого количества писем вы бы не просто перебирали список и создавали / доставляли письма. Вы можете использовать очередь для этого. Тем не менее, в общем, когда нет необходимости производить шаг рендеринга несколько раз, как бы вы это делали один раз и использовали этот результат для всех писем?

Потенциально мое незнакомство с ActionMailer подводит меня здесь.

1 Ответ

2 голосов
/ 25 июня 2011

Я не пробовал этого, но вызов почтовой программы просто возвращает простой старый объект Mail :: Message, полный тела.Таким образом, вы сможете просто захватить тело и использовать его повторно.

message = MyMailer.new_products(c, products)
message_body = message.body

customers.each do |c|
  mail = Mail.new do
    from    'yoursite@sample.com'
    to      c.email
    subject 'this is an email'
    body    message_body
  end
  mail.deliver
end

Возможно, вы даже сможете добиться большей «эффективности», дублируя сообщение

message = MyMailer.new_products(c, products)

customers.each do |c|
  mail = message.dupe()
  mail.to = c.email
  mail.deliver
end
...