Pigius Pigius - 11 months ago 43
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 Source

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