Reputation: 2685
I'm trying to learn how to read rubydocs. I'm sure there is something fundamentally basic that I have missed in trying to use these documents, but for now, I'm so frustrated that information is being presented to me, but without any form of intelligible user guide that goes along with it.
I want to amend my devise, so that users can nominate a group they want to join - in this case, an organisation where their email is changed to an organisation email, pending confirmation by the organisation owner.
I think this function (which I have copied below from the devise ruby docs) is going to help.
#postpone_email_change_until_confirmation_and_regenerate_confirmation_token ⇒ Object (protected)
253
# File 'lib/devise/models/confirmable.rb', line 247
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
@reconfirmation_required = true
self.unconfirmed_email = self.email
self.email = self.email_was
self.confirmation_token = nil
generate_confirmation_token
end
My problem is that I don't understand how it works or how to incorporate it in my app.
Do I add it to my user model (just copy & paste) and then put a line in my user controller for the update action, so that any change of email does each of those the steps listed in the method?
If I do that, what name do I give to the controller call?
In user.rb I have tried:
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
@reconfirmation_required = true
self.unconfirmed_email = self.email
self.email = self.email_was
self.confirmation_token = nil
generate_confirmation_token
end
In user controller - update action, I have tried:
if @user.update(user_params)
user.postpone_email_change_until_confirmation_and_regenerate_confirmation_token
Im clearly trying to do this incorrectly. What's not clear to me is how I'm supposed to use this function.
Can anyone see where I've gone wrong?
Upvotes: 0
Views: 271
Reputation: 2464
That method is in Confirmable
concern.
So, all you need is to define it inside your user.rb
For example
# Extensions
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable,
:lastseenable, :timeoutable
Consider to the :confirmable
symbol.
Then if you will change email before_update
and after_commit
callbacks will be called if all conditions will return true value
You can't call protected instance method from anywhere.
In case of protected methods, you can call them from the scope of any object belonging to the same class. This means that when you pass a Person object p1 as an argument to a method on another Person object p2, you can access all the protected methods of p1 within that method.
from here
module Confirmable
extend ActiveSupport::Concern
included do
# ...
after_commit :send_on_create_confirmation_instructions, on: :create, if: :send_confirmation_notification?
after_commit :send_reconfirmation_instructions, on: :update, if: :reconfirmation_required?
#...
before_update :postpone_email_change_until_confirmation_and_regenerate_confirmation_token, if: :postpone_email_change?
end
here is a place where callback is called.
And then devise will send reconfirmation email to user.unconfirmed_email
You may need to override reconfirmation instructions email. Here is an example:
# app/mailers/devise/mailer.rb
if defined?(ActionMailer)
class Devise::Mailer < Devise.parent_mailer.constantize
include Devise::Mailers::Helpers
def confirmation_instructions(record, token, opts = {})
@token = token
if record.pending_reconfirmation?
devise_mail(record, :reconfirmation_instructions, opts)
else
devise_mail(record, :confirmation_instructions, opts)
end
end
end
end
And the mailer view
# app/views/devise/reconfirmation_instructions.text.erb
Hello, <%= @resource.fullname %>!
Please reconfirm your new email: <%= your_url_with_@token" %>
--
WBR, support team
Hope that helps.
UPDATE
All you need to enable confirmation/reconfirmation is just to add needed strategy to your User
model
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable,
:lastseenable, :timeoutable
And override devise mailer
# app/mailers/devise/mailer.rb
if defined?(ActionMailer)
class Devise::Mailer < Devise.parent_mailer.constantize
include Devise::Mailers::Helpers
def confirmation_instructions(record, token, opts = {})
@token = token
if record.pending_reconfirmation?
devise_mail(record, :reconfirmation_instructions, opts)
else
devise_mail(record, :confirmation_instructions, opts)
end
end
end
end
Upvotes: 1