I want Recoverable module to send "invite" emails with reset password links for my users (the app is on invite only), I partially declare methods in initializer:
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
And recoverable is extended nicely, but it says that my mailer does not have invite_new_user method (rails console output):
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
but calling has method in the same console session:
1.9.2p290 :003 > ::Devise.mailer.method_defined? 'invite_new_user'
=> true
What am I missing?
Devise can be set-up for what you need:
1- Create a Mailer
class in app/mailers/auth_mailer.rb file and make it inherit from Devise::Mailer
class AuthMailer < Devise::Mailer
def invite_new_user(record)
devise_mail(record, :invitation_instructions)
end
end
2- Instruct Devise to use your class by editing config/initializers/devise.rb file and adding
config.mailer = 'AuthMailer'
3- (optional) If (and only if) you use a delay email sending such as SideKiq or DelayedJob you may need to eager load in development, or the delayed job may not find your AuthMailer
class. In config/environments/development.rb
config.eager_load = true
4- I personally would define your send_invite_user_instructions!
method in my User
class instead of patching Devise class
Side note: I'm not a big fan or doing a partial declaration of a class in Rails initializer, because depending on how the gem is designed you can have trouble with autoload : There is a gem (Monologue) that reload objects during run time, without running the initializers, so the monkey patch works well on the first call, but not on the next calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With