ste*_*392 26 passwords validation ruby-on-rails update-attributes
现在,用户可以编辑一些属性,而无需输入密码,因为我的验证设置如下:
validates :password, :presence =>true, :confirmation => true, :length => { :within => 6..40 }, :on => :create
validates :password, :confirmation => true, :length => { :within => 6..40 }, :on => :update, :unless => lambda{ |user| user.password.blank? }
Run Code Online (Sandbox Code Playgroud)
但是,在用户执行此操作后,将删除其密码 - update_attributes将其密码更新为"".这是我的更新定义:
def update
if @user.update_attributes(params[:user])
flash[:success] = "Edit Successful."
redirect_to @user
else
@title = "Edit user"
render 'edit'
end
end
Run Code Online (Sandbox Code Playgroud)
我也尝试使用另一种使用update_attribute的定义:
def save_ff
@user = User.find(params[:id])
@user.update_attribute(:course1, params[:user][:course1] )
@user.update_attribute(:course2, params[:user][:course2] )
@user.update_attribute(:course3, params[:user][:course3] )
@user.update_attribute(:course4, params[:user][:course4] )
redirect_to @user
end
Run Code Online (Sandbox Code Playgroud)
但出于某种原因,这是做同样的事情.如何在不更改密码的情况下更新某些用户属性?谢谢!
apn*_*ing 22
我没有意识到我昨天给你的解决方案会导致这个问题.抱歉.
好吧,从设计中获取灵感,您应该以这种方式更新控制器:
def update
params[:user].delete(:password) if params[:user][:password].blank?
if @user.update_attributes(params[:user])
flash[:success] = "Edit Successful."
redirect_to @user
else
@title = "Edit user"
render 'edit'
end
end
Run Code Online (Sandbox Code Playgroud)
cbe*_*ian 12
这篇博客文章展示了你想要做的事情的原则.
未显示但可能有用的是向模型添加访问器:
attr_accessor :new_password, :new_password_confirmation
attr_accessible :email, :new_password, :new_password_confirmation
Run Code Online (Sandbox Code Playgroud)
并在用户提供新密码的条件下提供所有所需的验证.
validates :new_password, :presence => true,
:length => { :within => 6..40 },
:confirmation => true,
:if => :password_changed?
Run Code Online (Sandbox Code Playgroud)
最后,我会添加一个检查,看看是否已设置encrypted_password以确定是否"password_changed?" 为了在新记录上要求密码.
def password_changed?
!@new_password.blank? or encrypted_password.blank?
end
Run Code Online (Sandbox Code Playgroud)
Ric*_*d W 10
我一直在努力解决这个问题并在圈子里转了一会儿,所以我想我会把我的Rails 4解决方案放在这里.
到目前为止我看到的答案都没有达到我的用例,它们似乎都涉及以某种方式绕过验证,但我希望能够验证其他字段以及密码(如果存在).另外,我没有在我的项目上使用设计,所以我无法使用任何特别的东西.
值得指出的是,这是一个2部分的问题:
步骤1 - 如果密码在控制器中为空,则需要从强参数中删除密码和确认字段:
if myparams[:password].blank?
myparams.delete(:password)
myparams.delete(:password_confirmation)
end
Run Code Online (Sandbox Code Playgroud)
第2步 - 您需要更改验证,以便在未输入密码时验证密码.我们不想要的是将它设置为空白,因此我们之前为什么要将它从参数中删除.
在我的情况下,这意味着在我的模型中将其作为验证:
validates :password, :presence => true, :confirmation => true, length: {minimum: 7}, :if => :password
Run Code Online (Sandbox Code Playgroud)
注意:if =>:password - 跳过检查是否未设置密码.
2017年答案:
在Rails 5中,正如 Michael Hartl 的教程所指出的,您在模型中获得以下内容就足够了:
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
Run Code Online (Sandbox Code Playgroud)
allow_nil: true是这里的关键。这允许用户编辑他/她的信息,而无需更改密码。
此时人们可能会认为这也将允许空用户注册;然而,通过使用自动验证密码是否存在has_secure_password于该方法中可以防止这种情况。create
这是User用于说明目的的演示模型:
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不知道如何使这项工作在设计中发挥作用。干杯。
# It smells
def update
if params[:user][:password].blank?
params[:user].delete :password
params[:user].delete :password_confirmation
end
if @user.update_attributes(params[:user])
flash[:success] = "Edit Successful."
redirect_to @user
else
@title = "Edit user"
render 'edit'
end
end
# Refactoring
class User < ActiveRecord::Base
...
def update_attributes(params)
if params[:password].blank?
params.delete :password
params.delete :password_confirmation
super params
end
end
...
end
def update
if @user.update_attributes(params[:user])
flash[:success] = "Edit Successful."
redirect_to @user
else
@title = "Edit user"
render 'edit'
end
end
# And little better
class User < ActiveRecord::Base
...
def custom_update_attributes(params)
if params[:password].blank?
params.delete :password
params.delete :password_confirmation
update_attributes params
end
end
...
end
def update
if @user.custom_update_attributes(params[:user])
flash[:success] = "Edit Successful."
redirect_to @user
else
@title = "Edit user"
render 'edit'
end
end
Run Code Online (Sandbox Code Playgroud)