これのREADMEにもありますが、Letter Opener (-Webも含む)をHerokuで使うにはちょっと注意が必要です。つまり、
- Letter Openerはデータを
#{Rails.root}/tmp/letter_opener
に保存する - Herokuはdyno (node) 間でデータのやりとりは出来ない設計
- ActionMailerの
deliver_later!
はActiveJobで実行するので、web dynoではなくworker dyno のファイルシステムにLetter Openerのデータを保存する
という状況なので、 #deliver_now!
で送信したものはLetter Openerで見えますが、 #deliver_later!
で送信したものは見えない、ということになります。
じゃあHeroku review appのときだけ #deliver_later!
を #deliver_now!
に置き換えればいいんですねということでApplicationMailerにこんな感じのhackを入れました。
ActionMailerの内部実装に強く依存しているのでRailsのアップデートなどで動かなくなる可能性はありますが、 Rails 4.2.x, 5.1.x あたりはこれで大丈夫そうです。
# rubocop:disable Style/MethodMissing class ApplicationMailer < ActionMailer::Base # Heroku web apps do not access worker's filesystem # https://github.com/fgrehm/letter_opener_web#usage-on-heroku # override def self.method_missing(method_name, *args) if action_methods.include?(method_name.to_s) MyMessageDelivery.new(self, method_name, *args) else super end end class MyMessageDelivery < ActionMailer::MessageDelivery # override def deliver_later! if Rails.env.heroku_review_app? deliver_now! else super end end # override def deliver_later if Rails.env.heroku_review_app? deliver_now else super end end end end