2
votes

I'm attempting to override devise's mailer, per this guide on using custom mailers.

# config/initializers/devise.rb

config.mailer = "AccountsMailer"

Really, I want to set the host dynamically for all mailer actions. But at the moment, it seems just a basic override of the reset_password_instructions method isn't even working.

# app/mailers/accounts_mailer.rb

class AccountsMailer < Devise::Mailer
  # allow use of before_filter
  include AbstractController::Callbacks

  def default_url_options
    { host: 'overridden.com' }
  end

  def reset_password_instructions(record, opts={})
    raise 'overridden'
    @host = 'overridden.co'
    super
  end

end

This makes me question if devise is even using my custom mailer.

# views/customers/mailer/reset_password_instructions.html.erb

<% puts "*Mail View*" %>
<% puts @host  %>
<% puts Devise.mailer %>
...

From my forman log when this message is sent:

mailer.1  | *Mail View*
mailer.1  |
mailer.1  | AccountsMailer
mailer.1  | Render customers/mailer/reset_password_instructions.html.erb

So, Devise claims to be using AccountsMailer, but the method override isn't working, since the message is sent instead of en exception being raised, ...


Relevant Setup

  • Rails 3.2.13
  • Ruby 1.9.3-p374
  • Devise 2.1.2
  • Devise-async 0.5.1
  • Sidekiq 2.12.0
  • Foreman 0.61.0
    • web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
    • db: postgres -D /usr/local/var/postgres
    • redis: redis-server /usr/local/etc/redis.conf
    • mailcatcher: mailcatcher -f
    • worker: bundle exec sidekiq -q high,2 -q default -e development -c 1
    • mailer: bundle exec sidekiq -q mailer -e development -c 1

Disclaimers

  • Yes, I restarted foreman / my server
  • I can't statically set the action_mailer.default_url_options[:host] in environments/<env>.rb, as the hostname is dynamic based on the type of user (staff and customers have different subdomains)
    • action_mailer.default_url_options doesn't accept a proc or block yet
  • Setting host name in each view is too WET for me to sleep well

An SO search didn't seem to see anyone else with this issue, nor did devise GH issues -- so what am I overlooking? Thanks!

1

1 Answers

2
votes

Ugh, this ended up being a version issue.

The documentation I was reading on the devise and devise-async pages was referencing current behavior. I was using 2.1.x and 0.5.x, respectively.

In those versions, overriding a mailer had to be done explicitly with devise-async using config.mailer (which I wasn't doing). As of 2.2.x and 0.7.x, devise-async uses Devise.mailer implicitly.

I've upgraded to 2.2.x and 0.7.x and this solved the issue with the above code.

Note: If you upgrade to 2.2.x from <= 2.1.x, note the backwards-incompatible changes introduced in 2.2