在我的应用中,用户可以编辑他们的个人资料信息。在编辑个人资料表单上,用户可以更改所有字段(姓名、职务等)。在同一个表单上是三个字段:current_password
、password
和password_confirmation
。我正在使用bcrypt
'shas_secure_password
功能进行密码验证。我根本不使用设计。
我希望用户只有在提供正确的当前密码时才能更改密码。我之前在update
我的用户控制器的方法中使用以下代码进行了此操作:
# Check if the user tried changing his/her password and CANNOT be authenticated with the entered current password
if !the_params[:password].blank? && !@user.authenticate(the_params[:current_password])
# Add an error that states the user's current password is incorrect
@user.errors.add(:base, "Current password is incorrect.")
else
# Try to update the user
if @user.update_attributes(the_params)
# Notify the user that his/her profile was updated
flash.now[:success] = "Your changes have been saved"
end
end
但是,这种方法的问题在于,如果当前密码不正确,它会丢弃对用户模型的所有更改。如果当前密码不正确,我想保存对用户模型的所有更改,但不保存密码更改。我试过像这样拆分 IF 语句:
# Check if the user tried changing his/her password and CANNOT be authenticated with the entered current password
if !the_params[:password].blank? && !@user.authenticate(the_params[:current_password])
# Add an error that states the user's current password is incorrect
@user.errors.add(:base, "Current password is incorrect.")
end
# Try to update the user
if @user.update_attributes(the_params)
# Notify the user that his/her profile was updated
flash.now[:success] = "Your changes have been saved"
end
这不起作用,因为即使当前密码不正确,用户也可以更改他/她的密码。单步执行代码时,虽然“当前密码不正确”。错误添加到@user
,通过该update_attributes
方法运行后,似乎忽略了此错误消息。
顺便说一句,该current_password
字段是我的用户模型中的虚拟属性:
attr_accessor :current_password
几个小时以来,我一直试图解决这个问题,所以我真的可以使用一些帮助。
谢谢!
解决方案
感谢papirtiger,我得到了这个工作。我从他的回答中稍微更改了代码。下面是我的代码。请注意,任何一个代码片段都可以正常工作。
在用户模型中(user.rb)
class User < ActiveRecord::Base
has_secure_password
attr_accessor :current_password
# Validate current password when the user is updated
validate :current_password_is_correct, on: :update
# Check if the inputted current password is correct when the user tries to update his/her password
def current_password_is_correct
# Check if the user tried changing his/her password
if !password.blank?
# Get a reference to the user since the "authenticate" method always returns false when calling on itself (for some reason)
user = User.find_by_id(id)
# Check if the user CANNOT be authenticated with the entered current password
if (user.authenticate(current_password) == false)
# Add an error stating that the current password is incorrect
errors.add(:current_password, "is incorrect.")
end
end
end
end
我的用户控制器中的代码现在很简单:
# Try to update the user
if @user.update_attributes(the_params)
# Notify the user that his/her profile was updated
flash.now[:success] = "Your changes have been saved"
end