Diary

@ssig33

Rails の ActionMailer で正しく view の helper を使う

Rails の ActionMailer では Rails ActionMailer helper とかで検索すると、「ActionMailer で helper メソッドを使用するには add_template_helper を使おう」というような記事が複数ヒットする

他にもたくさんこう書かれている記事がある。しかしなんとこれは実は間違ったやり方である。 ActionMailer::Base を継承したクラスで add_template_helper というメソッドが使えるのは ActionMailer::Base が include AbstractController::Helpers しているからで、では AbstractController::Helpers を実際に見てみると実はなんと add_template_helper は private なメソッドで Rails の利用者が使うことを想定していない。

で、簡単に調べた限り Rails 3.0 の時からそのようになっていた

結果として、このメソッドはこのコミットで削除されてしまい、そしてそのまま Rails 6.1 でこのコミットはリリースされた。おそらく結構いろんなところで Rails 6.1 にするだけでメール送信まわりが壊れていると思うのだが(すくなくとも俺がメンテしてるアプリ 4 個で壊れた)、もちろんこれをコミットした人やこれをリリースした人が悪いのではなくて、 private メソッドを使うバッドノウハウを広げていた人やそれを無批判に採用していた人が悪い。俺も悪い(自分でそのコードを書いたことはないが気にしたこともなかった)。

ではどうすべきだったか、というと Rails 3.0 の時点でそうであったように、以下のように書くのがよい

class HogeMailer < ActionMailer::Base
  helper :hogehoge # 使いたいヘルパーファイルをこのように指定する
end

とっても有名な OSS について 10 年以上にわたって間違った、とても悪いノウハウが広まっていて特に訂正される気配もなかった、というお話でした。

16 Dec 2020 Wed 13:07 (UTC)