2015-10-13 103 views
0

我正在關注此解決方案:Rails 4 - Allow password change only if current password is correctRails 4,如何在密碼更改時詢問當前密碼?

但是無論我輸入的是否是正確的當前密碼,我的密碼都會更新。這裏是我的代碼:

員工型號:

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 

這讓我覺得,可能是密碼前更新這個驗證被執行。我怎樣才能確定這一點,如果是這樣,我怎樣才能使它按正確的順序執行?

感謝

+0

您使用設計? – matanco

回答

1

這種方法

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 

回報nil如果不匹配的員工。當你測試的結果呢,在這裏:

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

您特別是如果結果== false測試。 nil並不等於false,也不是僱員對象,因此此測試將始終返回false,並且不會添加錯誤。我會改變這個方法:

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

的「除非」案件將被任何東西「falsy」,其中包括falsenil被觸發。

+0

另外,根據@ jonsnow的建議重構你的'authenticate'方法,因爲它更簡潔一些。否則,如果測試未通過,if塊將返回nil,這一事實會讓您感到困惑。 –

+0

謝謝你的建議是我所需要的 – Fermin

1

改變你的方法是這樣,檢查同一

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

你沒有什麼@jonsnerr - 對不起,這是一個很好的建議,我無法抗拒它。 –

+0

嗯,謝謝@MaxWilliams。 –

0

在設計的寶石,你可以使用update_with_password方法要求使用ST

當前密碼

其作品在軌道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