jedi
jedi

Reputation: 2207

Ruby - ActiveModel::SecurePassword not working

I have a simple ruby class with ActiveModel::Validations and ActiveModel::SecurePassword included, I provide all required attributes (below) to the new obkject but when I validate it it says it's false.

require 'active_model'
require 'bcrypt'

class User
  include ActiveModel::Validations
  include ActiveModel::SecurePassword

  attr_accessor :name, :email, :password, :password_digest

  def initialize(name:, email:, password:)
    @name, @email, @password = name, email, password
  end
  
  validates :name, :email, presence: true
  has_secure_password
end

user = User.new(
          name: "TestUser1",
          email: "[email protected]",
          password: "password"
        )

puts user.valid? => false

puts user.errors.messages => {:password=>["can't be blank"]}

puts user.password => password

According to the documentation here has_secure_password provides validations on password accessor:

  1. Password should be present.
  2. Password should be equal to its confirmation (provided password_confirmation is passed along).
  3. The maximum length of a password is 72 (required by bcrypt on which ActiveModel::SecurePassword depends)

What am I doing wrong? How's this object false?

EDIT I have also tried adding password_confirmation attribute but it didn't work either.

user.password_confirmation = "password"

puts user.valid? => false

puts user.errors.messages => {:password=>["can't be blank"]}

Upvotes: 0

Views: 180

Answers (2)

Vasiliy Ermolovich
Vasiliy Ermolovich

Reputation: 24627

Since you need to have password_digested filled by ActiveModel::SecurePassword you have to call User#password= setter method. But it's not happening when you set your password using @password = password in your initializer. To fix it you have set it using self.password = password:

def initialize(name:, email:, password:) 
  @name, @email = name, email
  self.password = password
end

Also you need to remove :password from attr_accessor call because SecurePassword provides it.

Upvotes: 2

Paul Byrne
Paul Byrne

Reputation: 1615

I believe you need to set the user.password_confirmation attribute as well.

http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password

Upvotes: 0

Related Questions