如何正确扩展Devise Recoverable?

时间:2012-05-01 17:43:30

标签: ruby-on-rails ruby devise

我希望Recoverable模块为我的用户发送带有重置密码链接的“邀请”电子邮件(该应用仅限邀请),我在初始化程序中部分声明了方法:

module Devise
  class Mailer
    def invite_new_user(record)
      devise_mail(record, :invitation_instructions)
    end
  end
end

module Devise
  module Models
    module Recoverable
      def send_invite_user_instructions!
        return unless status == User::STATUS_PENDING
        generate_reset_password_token!
        ::Devise.mailer.invite_new_user(self).deliver
      end
    end
  end
end

可恢复性很好,但它说我的邮件程序没有invite_new_user方法(rails console输出):

1.9.2p290 :002 > user.send_invite_user_instructions! 
  User Load (1.4ms)  SELECT "users".* FROM "users" WHERE "users"."reset_password_token" = 'zMQK1CEXYupjNKpH8dph' LIMIT 1
   (0.3ms)  BEGIN
   (15.0ms)  UPDATE "users" SET "reset_password_token" = 'zMQK1CEXYupjNKpH8dph', "updated_at" = '2012-05-01 17:40:32.085256' WHERE "users"."id" = 59
   (4.5ms)  COMMIT
NoMethodError: undefined method `invite_new_user' for Devise::Mailer:Class

但在同一控制台会话中调用has方法:

1.9.2p290 :003 > ::Devise.mailer.method_defined? 'invite_new_user'
 => true 

我错过了什么?

1 个答案:

答案 0 :(得分:2)

设计可以满足您的需求:

1 - 在app / mailers / auth_mailer.rb文件中创建一个Mailer类,并使其继承自Devise::Mailer

class AuthMailer < Devise::Mailer
  def invite_new_user(record)
    devise_mail(record, :invitation_instructions)
  end
end

2 - 通过编辑config / initializers / devise.rb文件并添加

,指示Devise使用您的课程
config.mailer = 'AuthMailer'

3-(可选)如果(仅限于)您使用延迟电子邮件发送,例如SideKiq或DelayedJob,您可能需要在开发中急切加载,或者延迟工作可能找不到您的AuthMailer课程。在config / environments / development.rb

config.eager_load = true

4 - 我个人会在我的send_invite_user_instructions!课程中定义您的User方法,而不是修补Devise类


旁注:我不是一个大粉丝或在Rails初始化程序中做一个类的部分声明,因为根据宝石的设计方式你可能会遇到自动加载问题:有一个宝石(独白)在运行时重新加载对象,而不运行初始化程序,因此猴子补丁在第一次调用时运行良好,但在下次调用时不运行。