1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ActionMailerに、複数のメールを一括でエンキューするメソッドが追加された

Last updated at Posted at 2025-12-15

はじめに

app/mailers/test_mailer.rb
class TestMailer < ApplicationMailer
  def sample_email(user)
    @user = user
    mail(to: @user.email_address, subject: 'Sample Email')
  end
end
app/jobs/delivery_test_mailer_job.rb

class TestMailerBulkSendJob < ApplicationJob
    def perform
        users = User.all # ここは適当な条件

        # メールをエンキューする処理 
    end
end

上記のように、メールを複数件送信する場合、エンキューする処理をどのように書きますか?
こんな方法あるよなを書きつつ、Rails8.1で追加されたメソッドについて紹介します。

書き方

素直にループしてキューイングする

app/jobs/delivery_test_mailer_job.rb

class TestMailerBulkSendJob < ApplicationJob
    def perform
        users = User.all # ここは適当な条件

        users.each do |user|
            TestMailer.sample_email(user).deliver_later
        end
    end
end

シンプルですね。
件数が数千件になってくると、1件ずつエンキューするのはパフォーマンス的に影響が出てきそうです。

ActiveJob.perform_all_later を利用する

Rails 7.1にて追加されたActiveJob.perform_all_later を使って、複数件のメールを一括でエンキューすることができます。

app/jobs/delivery_test_mailer_job.rb

class TestMailerBulkSendJob < ApplicationJob
    def perform
        users = User.all # ここは適当な条件

        delivery_jobs = []

        users.each do |user|
            delivery_jobs << ActionMailer::MailDeliveryJob.new(
                'TestMailer',
                'sample_email',
                'deliver_now',
                args: [admin_user]
            )
        end

        ActiveJob.perform_all_later(delivery_jobs)
    end
end

ActionMailer::MailDeliveryJobのObjectを明示して生成する必要があるため、若干の冗長さがあります。

ActionMailer.deliver_all_later を利用する

Rails8.1からは、以下のように書くことができるようになりました。

app/jobs/delivery_test_mailer_job.rb
class TestMailerBulkSendJob < ApplicationJob
    def perform
        users = User.all # ここは適当な条件

        deliveries = []

        users.each { |user| deliveries << TestMailer.sample_email(user) }

        ActionMailer.deliver_all_later(deliveries)
    end
end

実装を見てみると、ActiveJob.perform_all_later を使っていて、前述した書き方のラッパーのようなイメージです。
パフォーマンス的には大きく変わることはなさそうですが、だいぶスッキリかけるようになった印象があります。

ActionMailerを使っていて、大量件数のメール送信をしている箇所があれば、積極的に使っていきたいです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?