Pigius Pigius - 3 months ago 13
Ruby Question

Custom mailer for other than admin and user in Devise Rails

I have a problem, with Devise. I created new role other than admin and user in devise Rails. Here how it looks like in user.rb model

class User < ActiveRecord::Base
PANEL_LEVELS = [PANEL_LEVEL_NORMAL = 'normal', PANEL_LEVEL_INACTIVE_MODERATOR = 'inactive_moderator', PANEL_LEVEL_DESIGNER = 'moderator']


When somebody creates new moderator account, it will become inactive moderator.

Main problem for me, is to send custom confirmation mail to moderator, this is how I tried to do it from custom_devise_mailer:

def confirmation_instructions(record, token, opts = {})
if record.class.name == 'User'
opts[:template_path] = 'devise_users/mailer'
else if resource.panel_level == User::PANEL_LEVEL_INACTIVE_MODERATOR
opts[:template_path] = 'devise_moderators/mailer'
else
opts[:template_path] = 'devise_admins/mailer'
end
end
opts[:template_name] = :confirmation_instructions
super


end


Where

resource.panel_level = User::PANEL_LEVEL_INACTIVE_MODERATOR if params.fetch('account') { nil } == 'moderator'


But it's sending default mail for devise_user. Naturally I have views for moderator mailer, and method for sending it.

Answer

Your if statements are very twisted. You can increase readability by simplifying them, by abstracting some logic into decorators. I gues that you have decorators for Admin and User classes:

# in UserDecorator
def devise_mailer
  if object.panel_level = User::PANEL_LEVEL_INACTIVE_MODERATOR
    'devise_moderators/mailer'
  else
    'devise_users/mailer'
  end
end

# in AdminDecorator
def devise_mailer
  'devise_admins/mailer'
end

Having that your custom_devise_mailer.rb can be simplified to:

def confirmation_instructions(record, token, opts = {})
  opts[:template_path] = resource.decorate.devise_mailer
  super
end