2
votes

I have a custom mailer (UserMailer.rb) and a few methods to override the default Devise methods for the welcome email and forgot password emails. The mailer uses a custom template to style the emails--and it works great.

In config/initializers, I have a file with

module Devise::Models::Confirmable
    # Override Devise's own method. This one is called only on user creation, not on subsequent address modifications.

  def send_on_create_confirmation_instructions
    UserMailer.welcome_email(self).deliver
  end

  ...
end

(Again, UserMailer is setup and works great for the welcome email and reset password email.)

But what's not working is the option to "Resend confirmation instructions." It sends with the default Devise styling and I want it to use the styling of my mailer layout. I know I can manually add the layout to the default Devise layout, but I'd like to keep DRY in effect and not have to do that.

I've tried overriding the send_confirmation_instructions method found here, but I'm getting a wrong number of arguments (1 for 0) error in create(gem) devise-2.2.3/app/controllers/devise/confirmations_controller.rb at

7 # POST /resource/confirmation
8   def create
9     self.resource = resource_class.send_confirmation_instructions(resource_params)

In my initializer file, I'm able to get to this error by adding a new override for Devise, but I'm probably not doing this correctly:

module Devise::Models::Confirmable::ClassMethods
  def send_confirmation_instructions
    UserMailer.send_confirmation_instructions(self).deliver
  end
end

Any ideas?

1

1 Answers

5
votes

You don't have to go through that initializer to do that. I've done this by overriding the confirmations controller. My routes for devise look like:

devise_for :user, :path => '', :path_names => { :sign_in => 'login', :sign_out => 'logout', :sign_up => 'signup'}, 
:controllers => { 
  :sessions => "sessions", 
  :registrations => "registrations", 
  :confirmations => "confirmations"
}

Then, create the confirmations_controller and extend the Devise::ConfirmationsController to override:

class ConfirmationsController < Devise::ConfirmationsController

In that controller, I have a create method to override the default:

def create

  @user = User.where(:email => params[:user][:email]).first

  if @user && @user.confirmed_at.nil?
    UserMailer.confirmation_instructions(@user).deliver
    flash[:notice] = "Set a notice if you want"
    redirect_to root_url
  else
    # ... error messaging or actions here
  end

end

Obviously, in UserMailer you can specify the html/text templates that will be used to display the confirmation message. confirmation_token should be a part of the @user model, you can use that to create the URL with the correct token:

<%= link_to 'Confirm your account', confirmation_url(@user, :confirmation_token => @user.confirmation_token) %>