Baby step - 思考と実験の足跡

日常のちょっとした、気になって試したこと集です。

Rails6.1で追加されたActionMailer DeliveryJobのDeprecatedを解消する

終わってみれば簡単だったけど、検索してもそのままそのものズバリの記事が見つからなかったのでメモ

環境

  • Ruby: 2.7
  • Rails: 6.1.4.4

前提

Rails5.2時代に、以下の記事を参考にActionMailerを独自のActiveJobで動かしていた。

cf. https://www.bigbinary.com/blog/rails-5-2-allows-mailers-to-use-custom-active-job-class

class CustomMailDeliveryJob < ApplicationJob
  queue_as :mailers

  def perform(mailer, mail_method, delivery_method, *args)
    mailer.constantize.public_send(mail_method, *args).send(delivery_method)
  end
end

問題

Rails6.1にアップデートした時、以下のDEPRECATION WARNINGが表示されるようになった。

DEPRECATION WARNING: In Rails 6.2, Action Mailer will pass the mail arguments inside the `:args` keyword argument.
The `perform` method of the CustomMailDeliveryJob needs to change and forward the mail arguments
from the `args` keyword argument.

The `perform` method should now look like:

`def perform(mailer, mail_method, delivery, args:)`

結論

WARNINGに書かれている通り、以下のように変更することで解決した。

-  def perform(mailer, mail_method, delivery_method, *args)
+  def perform(mailer, mail_method, delivery_method, args:)
    mailer.constantize.public_send(mail_method, *args).send(delivery_method)
  end

調査内容

今回のWARNINGは、以下のPRにて追加された。

cf. https://github.com/rails/rails/pull/39277

※ railsリポジトリのPRで「ActionMailer perform deprecated」で検索したら見つかった

まず、performの引数の中身を確認した。 例として、以下の処理がある。

PostMailer.send_mail(1, User.first).deliver_later

この処理を実行した時preformの各引数は以下のようになった。

puts mailer # => PostMailer
puts mail_method # => send_mail
puts delivery_method # => deliver_later
puts args # => [1, #<User>]

*argsargs:に変更しても結果は変わらなかったので、この変更で良さそう。

注意点

public_sendに渡すargsは可変長引数のままにしておくこと。

argsとして渡したら、deliver_laterでメール送信が失敗していた。