Search code examples
ruby-on-railsruby-on-rails-3deviseactionmailerinvite

devise_invitable: Confirm after Invitation


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

Solution

  • 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