在我的应用程序中,用户可以编辑他们的个人资料信息。在编辑个人资料表单上,用户可以更改所有字段(姓名、职务等)。在同一个表单上有三个字段:current_password
, password
, and password_confirmation
。我在用bcrypt
's has_secure_password
密码验证功能。我根本不使用 Devise。
我希望用户只有在提供了正确的当前密码的情况下才能更改密码。我之前已经使用以下代码进行了此工作update
我的用户控制器的方法:
# Check if the user tried changing his/her password and CANNOT be authenticated with the entered current password
if !the_params[:password].blank? && [email protected] /cdn-cgi/l/email-protection(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? && [email protected] /cdn-cgi/l/email-protection(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
我已经花了几个小时试图解决这个问题,所以我真的需要一些帮助。
Thanks!
Solution
谢谢纸虎 https://stackoverflow.com/users/544825/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