Search code examples
ruby-on-railsdeviseruby-on-rails-5

Pass variable from Devise controller to custom mailer?


I use Devise for authentication in my Rails app.

In my registrations_controller I have a variable like this:

class RegistrationsController < Devise::RegistrationsController
  def create
    foo = "bar"
    super
  end
end

In my customized mailer I then try to access the foo variable. The opts argument seems to be the one to look at:

class CustomMailer < Devise::Mailer
  helper :application
  include Devise::Controllers::UrlHelpers

  def confirmation_instructions(record, token, opts={})
    Rails.logger.error opts[:foo].inspect
    super
  end
end

But how do I pass on the foo variable on, without overwriting a lot of methods?


Solution

  • First, read about Devise custom mailer to familiarize yourself with the process.

    Briefly this is how you'd go about doing it:

    in config/initializers/devise.rb:

    config.mailer = "DeviseMailer"
    

    Now you can just use DeviseMailer like you'd do for any other mailer in your project:

    class DeviseMailer < Devise::Mailer   
      helper :application # gives access to all helpers defined within `application_helper`.
      include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url`
      default template_path: 'devise/mailer' # to make sure that your mailer uses the devise views
         ...
    
      def confirmation_instructions(record, token, opts={})
        headers["Custom-header"] = "Bar"
        opts[:from] = 'my_custom_from@domain.com'
        opts[:reply_to] = 'my_custom_from@domain.com'
        super
      end
    
          ...
       end
    

    You can now call the confirmation_instructions in your project and pass whatever variable you want to be able to access in your template.

    i.e:

    Calling the confirmation_instructions method:

     DeviseMailer.confirmation_instructions(User.first, "faketoken", {})
    

    confirmation_instructions.html.erb

     <p> And then override the template according to you. <p>
    

    Hope this will help you :)