devise_invitable: Confirm after Invitation
Asked Answered
C

2

5

I override devise's confirm! method to send a welcome message to my users:

class User < ActiveRecord::Base

  devise :invitable, :database_authenticatable, :registerable, :recoverable, 
         :rememberable, :confirmable, :validatable, :encryptable

  # ...

  # Devise confirm! method overriden
  def confirm!
    UserMailer.welcome_alert(self).deliver
    super
  end

end

With devise_invitable when the user accept the invitation and set his password the confirm! method is never triggered, is it possible to force it? How does devise_invitable confirms the User?

Or maybe I can override the accept_invite (or whatever its called) method the same way?

I want that invited users remain unconfirmed, and then confirmed upon accepting the invitation.

Thanks, any help very appreciated!

Original Source

UPDATE

Looking through devise_invitable model I found the two methods who may be causing this misbehavior:

  # Accept an invitation by clearing invitation token and confirming it if model
  # is confirmable
  def accept_invitation!
    if self.invited? && self.valid?
      self.invitation_token = nil
      self.save
    end
  end

  # Reset invitation token and send invitation again
  def invite!
    if new_record? || invited?
      @skip_password = true
      self.skip_confirmation! if self.new_record? && self.respond_to?(:skip_confirmation!)
      generate_invitation_token if self.invitation_token.nil?
      self.invitation_sent_at = Time.now.utc
      if save(:validate => self.class.validate_on_invite)
        self.invited_by.decrement_invitation_limit! if self.invited_by
        !!deliver_invitation unless @skip_invitation
      end
    end
  end
Cunctation answered 18/5, 2011 at 23:57 Comment(1)
Figured out: gist.github.com/982181Cunctation
C
9
class User < ActiveRecord::Base
  devise :invitable, :database_authenticatable, :registerable, :recoverable, 
         :rememberable, :confirmable, :validatable, :encryptable

  # ...

  # devise confirm! method overriden
  def confirm!
    welcome_message
    super
  end

  # devise_invitable accept_invitation! method overriden
  def accept_invitation!
    self.confirm!
    super
  end

  # devise_invitable invite! method overriden
  def invite!
    super
    self.confirmed_at = nil
    self.save
  end

private

  def welcome_message
    UserMailer.welcome_message(self).deliver
  end

end
Cunctation answered 27/5, 2011 at 16:14 Comment(1)
Great, thanks! Just a minor remark to this with regards to validation. accept_invitation! might not produce a valid model, e.g. if password restrictions are not met as the invited user accepts the invitation. self.confirm! if model.valid? to catch this and not let the welcome email slip out in case of validation error.Centennial
S
6

I tried benoror's answer and at first it appeared to work - but when you a user accepts the invitation and fills in the form as invalid it will actually override the token invalidating the invitation.

Instead, a callback is available to do this:

class User < ActiveRecord::Base

  devise :invitable, :database_authenticatable, :registerable, :recoverable, 
     :rememberable, :confirmable, :validatable, :encryptable

  after_invitation_accepted :send_welcome_email


  def send_welcome_email
  end

end
Servomotor answered 18/1, 2015 at 0:47 Comment(1)
Times have changed. this is the answer. Thanks @ServomotorGesner

© 2022 - 2024 — McMap. All rights reserved.