Rails
ActionMailer
RubyOnRails

ActionMailerのdeliver_laterではシリアライズが必要(な時がある)

More than 1 year has passed since last update.

結論はタイトルの通り

「ActionMailerでメールを送ろうとしたら、エラーがでる」ことがあった。エラーの内容は

ActiveJob::SerializationError (Unsupported argument type: User)

であった。この時、メールは


***_controller.rb

ApplicationMailer.welcome_email(@user).deliver_later


と書いていた。RailsのActionMailerは、ActiveJobと統合しており、リクエストレスポンス通信のバックでメールを非同期に送信する機能がついている。それが、「.deliver_later」である。

ところが、この場合、渡す引数はシリアライズされたもの、つまり、


//edgeapi.rubyonrails.org/より

NilClass, Integer, Fixnum, Float, String, TrueClass, FalseClass, Bignum, BigDecimal, and objects that can be represented as GlobalIDs (ex: Active Record)


を指定する必要がある。一方で、deliver_nowは、ActiveJobを利用しないので、@user配列を引数にとっても問題ない。ということで、特に重たい処理でない場合は、deliver_nowを使っておけば良さそうだ。

そもそも、シリアライズとは、直列化のことで、「ある環境において存在しているオブジェクトを、バイト列やXMLフォーマットに変換することをいう。」(wikipediaより)ということ。以下が具体例も交えてわかりやすく解説してくれている。

https://qiita.com/jnchito/items/68e91e9bf46f960a79e4

以下ドキュメントによれば、ActiveJobに渡されるオブジェクトが、GlobalIDを使っていれば、シリアライズを求めることはないらしい。

https://railsguides.jp/active_job_basics.html