【Rails】devise_mailで送信元メールアドレスを動的に変える
Railsでdeviseを使ってメール送信機能を作るとき、送信元のアドレスは通常いつも同じで済むことが多い。
セオリーなのは、 config/initializers/devise.rb
にある config.mailer_sender
の項目に送信元アドレスを書くことだろう。
# ==> Mailer Configuration # Configure the e-mail address which will be shown in Devise::Mailer, # note that it will be overwritten if you use your own mailer class # with default "from" parameter. config.mailer_sender = 'from@example.com'
また、Mailerの種類によって異なる役割のメールアドレスを送りたいときなどは、各Mailerクラスの冒頭に default
をつけることで、そのMailerで使われる送信元アドレスを上書きできる。
class UserMailer < ApplicationMailer default from: "info@udomomo.com" ... end
しかし先日、同じMailerによるメールでも送信元アドレスを出し分ける必要が生じた。そのサービスではユーザが使うドメインによってテンプレートを出し分けており、送信元アドレスもドメインによって出し分けたかったのだ。
これをdeviseの機能でどう実現すれば良いかしばらく悩んだが、 devise_mail
メソッドに opt
という引数があり、それを使うことで解決できた。
# mail_address変数に送信元アドレスを入れておく opt.store("from": mail_address) devise_mail(record, :mail_title, opt)
この方法は、devise_mailの実装を見ることで理解できる。
def devise_mail(record, action, opts = {}, &block) initialize_from_record(record) mail headers_for(action, opts), &block end ... def headers_for(action, opts) headers = { subject: subject_for(action), to: resource.email, from: mailer_sender(devise_mapping), reply_to: mailer_reply_to(devise_mapping), template_path: template_paths, template_name: action }.merge(opts) @email = headers[:to] headers end
devise_mail
は、メールヘッダの設定を行ったうえでActionMailerの mail
メソッドを使ってメールを送信しているが、その際 opt
引数に渡されたハッシュを merge
している。このmerge
とは2つのhashを合成するためのメソッドで、キーが重複した場合デフォルトでは後から指定した値で上書きされる。つまり、上書きしたいheaderの項目を opt
内で指定すれば、 devise_mail
を呼び出すタイミングで設定を変えることができる。
RailsのMailerはあまり使い慣れていないので、もっとスマートな方法があれば知りたい。