# module Devise::Models::Confirmable

Confirmable is responsible to verify if an account is already confirmed to sign in, and to send emails with confirmation instructions. Confirmation instructions are sent to the user email after creating a record and when manually requested by a new confirmation instruction request.

## Options

Confirmable adds the following options to devise_for:

    * +allow_unconfirmed_access_for+: the time you want to allow the user to access his account
      before confirming it. After this period, the user access is denied. You can
      use this to let your user access some features of your application without
      confirming the account, but blocking it after a certain period (ie 7 days).
      By default allow_unconfirmed_access_for is zero, it means users always have to confirm to sign in.
    * +reconfirmable+: requires any email changes to be confirmed (exactly the same way as
      initial account confirmation) to be applied. Requires additional unconfirmed_email
      db field to be setup (t.reconfirmable in migrations). Until confirmed new email is
      stored in unconfirmed email column, and copied to email column on successful
      confirmation.

## Examples

    User.find(1).confirm!      # returns true unless it's already confirmed
    User.find(1).confirmed?    # true/false
    User.find(1).send_confirmation_instructions # manually send instructions

### Public Instance Methods

active_for_authentication?() click to toggle source

Overwrites active_for_authentication? for confirmation by verifying whether a user is active to sign in or not. If the user is already confirmed, it should never be blocked. Otherwise we need to calculate if the confirm time has not expired for this user.

    # File lib/devise/models/confirmable.rb, line 87
    def active_for_authentication?
      super && (!confirmation_required? || confirmed? || confirmation_period_valid?)
    end

confirm!() click to toggle source

Confirm a user by setting it’s confirmed_at to actual time. If the user is already confirmed, add an error to email field. If the user is invalid add errors

    # File lib/devise/models/confirmable.rb, line 42
    def confirm!
      pending_any_confirmation do
        self.confirmation_token = nil
        self.confirmed_at = Time.now.utc

        if self.class.reconfirmable && unconfirmed_email.present?
          @bypass_postpone = true
          self.email = unconfirmed_email
          self.unconfirmed_email = nil

          # We need to validate in such cases to enforce e-mail uniqueness
          save(:validate => true)
        else
          save(:validate => false)
        end
      end
    end

confirmed?() click to toggle source

Verifies whether a user is confirmed or not

    # File lib/devise/models/confirmable.rb, line 61
    def confirmed?
      !!confirmed_at
    end

headers_for(action) click to toggle source

    # File lib/devise/models/confirmable.rb, line 102
    def headers_for(action)
      headers = super
      if action == :confirmation_instructions && pending_reconfirmation?
        headers[:to] = unconfirmed_email
      end
      headers
    end

inactive_message() click to toggle source

The message to be shown if the account is inactive.

    # File lib/devise/models/confirmable.rb, line 92
    def inactive_message
      !confirmed? ? :unconfirmed : super
    end

pending_reconfirmation?() click to toggle source

    # File lib/devise/models/confirmable.rb, line 65
    def pending_reconfirmation?
      self.class.reconfirmable && unconfirmed_email.present?
    end

resend_confirmation_token() click to toggle source

Resend confirmation token. This method does not need to generate a new token.

    # File lib/devise/models/confirmable.rb, line 79
    def resend_confirmation_token
      pending_any_confirmation { send_confirmation_instructions }
    end

send_confirmation_instructions() click to toggle source

Send confirmation instructions by email

    # File lib/devise/models/confirmable.rb, line 70
    def send_confirmation_instructions
      self.confirmation_token = nil if reconfirmation_required?
      @reconfirmation_required = false

      generate_confirmation_token! if self.confirmation_token.blank?
      self.devise_mailer.confirmation_instructions(self).deliver
    end

skip_confirmation!() click to toggle source

If you don’t want confirmation to be sent on create, neither a code to be generated, call skip_confirmation!

    # File lib/devise/models/confirmable.rb, line 98
    def skip_confirmation!
      self.confirmed_at = Time.now.utc
    end

### Protected Instance Methods

after_password_reset() click to toggle source

    # File lib/devise/models/confirmable.rb, line 161
    def after_password_reset
      super
      confirm! unless confirmed?
    end

confirmation_period_valid?() click to toggle source

Checks if the confirmation for the user is within the limit time. We do this by calculating if the difference between today and the confirmation sent date does not exceed the confirm in time configured. Confirm_within is a model configuration, must always be an integer value.

Example:

    # allow_unconfirmed_access_for = 1.day and confirmation_sent_at = today
    confirmation_period_valid?   # returns true

    # allow_unconfirmed_access_for = 5.days and confirmation_sent_at = 4.days.ago
    confirmation_period_valid?   # returns true

    # allow_unconfirmed_access_for = 5.days and confirmation_sent_at = 5.days.ago
    confirmation_period_valid?   # returns false

    # allow_unconfirmed_access_for = 0.days
    confirmation_period_valid?   # will always return false

    # File lib/devise/models/confirmable.rb, line 136
    def confirmation_period_valid?
      confirmation_sent_at && confirmation_sent_at.utc >= self.class.allow_unconfirmed_access_for.ago
    end

confirmation_required?() click to toggle source

Callback to overwrite if confirmation is required or not.

    # File lib/devise/models/confirmable.rb, line 113
    def confirmation_required?
      !confirmed?
    end

generate_confirmation_token() click to toggle source

Generates a new random token for confirmation, and stores the time this token is being generated

    # File lib/devise/models/confirmable.rb, line 152
    def generate_confirmation_token
      self.confirmation_token = self.class.confirmation_token
      self.confirmation_sent_at = Time.now.utc
    end

generate_confirmation_token!() click to toggle source

    # File lib/devise/models/confirmable.rb, line 157
    def generate_confirmation_token!
      generate_confirmation_token && save(:validate => false)
    end

pending_any_confirmation() { || ... } click to toggle source

Checks whether the record requires any confirmation.

    # File lib/devise/models/confirmable.rb, line 141
    def pending_any_confirmation
      if !confirmed? || pending_reconfirmation?
        yield
      else
        self.errors.add(:email, :already_confirmed)
        false
      end
    end

postpone_email_change?() click to toggle source

    # File lib/devise/models/confirmable.rb, line 172
    def postpone_email_change?
      postpone = self.class.reconfirmable && email_changed? && !@bypass_postpone
      @bypass_postpone = nil
      postpone
    end

postpone_email_change_until_confirmation() click to toggle source

    # File lib/devise/models/confirmable.rb, line 166
    def postpone_email_change_until_confirmation
      @reconfirmation_required = true
      self.unconfirmed_email = self.email
      self.email = self.email_was
    end

reconfirmation_required?() click to toggle source

    # File lib/devise/models/confirmable.rb, line 178
    def reconfirmation_required?
      self.class.reconfirmable && @reconfirmation_required
    end