Rails 4、修改密码时如何查询当前密码?

Rails 4, how to ask for current password in password change?

我正在遵循这个解决方案:

但是无论我是否输入正确的当前密码,我的密码都会更新。这是我的代码:

员工模型:

class Employee < ActiveRecord::Base
    attr_accessor :password, :current_password

    def self.authenticate(user, password)  
        employee = find_by_code(user)
        if employee && employee.password_hash == BCrypt::Engine.hash_secret(password, employee.password_salt)  
            employee  
        end  
    end  

    validates_presence_of :current_password, if: :validate_password?, on: :update
    validate :current_password_is_correct, if: :validate_password?, on: :update

    def current_password_is_correct
        if Employee.authenticate(code, current_password) == false 
            errors.add(:current_password, "Wrong password.")
        end
    end

    def validate_password?
        !password.blank?
    end
end

如果我将 current_password_is_correct 更改为此,它会正确显示错误:

def current_password_is_correct
    if Employee.authenticate(code, current_password) == false || true
        errors.add(:current_password, "Wrong password.")
    end
end

这让我觉得密码可能在执行此验证之前已更新。我怎样才能确定这一点,如果是这样,我怎样才能让它以正确的顺序执行?

谢谢

这个方法

def self.authenticate(user, password)  
    employee = find_by_code(user)
    if employee && employee.password_hash == BCrypt::Engine.hash_secret(password, employee.password_salt)  
        employee  
    end  
end  

returns nil 如果它与员工不匹配。当你测试它的结果时,这里:

def current_password_is_correct
    if Employee.authenticate(code, current_password) == false 
        errors.add(:current_password, "Wrong password.")
    end
end

你专门测试一下结果== falsenil 不等于 false,员工也不反对,所以这个测试总是 return false,永远不会添加错误。我会将此方法更改为:

def current_password_is_correct
  unless Employee.authenticate(code, current_password)
    errors.add(:current_password, "Wrong password.")
  end
end

"unless" 案例将由任何 "falsy" 触发,其中包括 falsenil

像这样改变你的方法,并检查相同的方法

def self.authenticate(user, password)  
    employee = find_by_code(user)
    employee && employee.password_hash == BCrypt::Engine.hash_secret(password, employee.password_salt)
end

在 Devise gem 中,您可以使用 update_with_password 方法通过 st

询问当前密码

它适用于 rails 4 和 5。

def update_password
    @user = User.find(current_user.id)
    if @user.update_with_password(password_params)
    end 
end

private
def password_params
    params.require(:user).permit(:password, :password_confirmation, :current_password)
end