Rails update_attributes 老是更新不成功,也没错误提示。

lin_style · September 19, 2012 · Last by chentianwen replied at September 19, 2012 · 4691 hits

#设置 def setting @user_setting = User.new
end

def setting_commit @user_setting = User.new(params[:user])

#安全校验注意 if @user_setting.nick_name && @user.nick_name != @user_setting.nick_name if [email protected]_attributes(:nick_name=> @user_setting.nick_name) logger.error("Err, setting update_attributes nick_name failed. userid:#{@user.id}")
return render(:action =>"setting")
end end

if @user.contact_me != @user_setting.contact_me if [email protected]_attributes(:contact_me=>@user_setting.contact_me) logger.error("Err, setting update_attributes contact_me failed. userid:#{@user.id}") return render(:action =>"setting") end end

日志打出来是 Started POST "/user_index/setting_commit" for 192.168.56.1 at 2012-09-19 09:34:27 +0800 Processing by UserIndexController#setting_commit as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"S2SaDwM5IUd7+eAurpq+qAJi/uY3UHcvHjz+oCSlWvc=", "user"=>{"nick_name"=>"adddd", "contact_me"=>""}, "commit"=>"提交"} DEPRECATION WARNING: Calling set_primary_key is deprecated. Please use self.primary_key = 'the_name' instead. (called from class:User at /home/lindp/Programmer/GitHub/jzns/jzns/app/models/user.rb:5) User Load (0.3ms) SELECT users.* FROM users WHERE users.id = 2 LIMIT 1 (0.2ms) BEGIN User Exists (0.5ms) SELECT 1 FROM users WHERE (users.nick_name = BINARY 'adddd' AND users.id != 2) LIMIT 1 (0.2ms) ROLLBACK Err, setting update_attributes nick_name failed. userid:2

为什么 ROLLBACK 了??User Exists 这个原因有点看不懂,SELECT 1,这不肯定有值吗??

#1 楼 @hooopo 晕,他为什么提示密码字段不能为空??我没更新那个字段呀

你设置的是“密码”字段不能为空吧,在验证上加上一个 :on => :create,声明只有 create 的时候校验就可以了

Unknow user #5 September 19, 2012

1、你提交的参数里会不会有密码 2、你的用户是不是真的没密码

是不是用了 ActiveModel::SecurePassword,它里面加了密码不能为空的校验。

#3 楼 @hooopo #4 楼 @chinacheng

我有用了 gem 'bcrypt-ruby' 这个包,password 是个虚拟的字段,数据库里对的是 passward_digest.. 但是我没更新密码这个字段啊??

#6 楼 @Rei 应该是这个问题,我现在设置了 :on => :create .那要是哪天有密码重新设置功能了,那这步校验不是又错过了。。 #4 楼 @chinacheng

#8 楼 @lin_style 有两个方法:

  1. 为空的时候设随机密码
  2. 重写 SecurePassword 模块的一些方法,允许不设密码

后续各有需要注意的地方。一开始为什么会有密码为空的用户?

#9 楼 @Rei 是这样: 用了 gem 'bcrypt-ruby',在数据库里是 passward_digest 这个字段保存加密后的密码。

代码里, password_field :password password_field :password_confirmation 这两个用来确认密码是否一致

在 model 里, #密码 (password) validates_presence_of :password, :on => :create, :message => "密码不能为空" validates_length_of :password, :on => :create, :in => 6..15, :message => "密码长度在 6-15"

has_secure_password #确认两次是否一样 validates_presence_of :password,:on => :create, :message => "两次输入密码不一致"

可能就是你在前几楼说的,password 内部不让为空了。

重置密码这种特殊功能特殊对待,必要的程序逻辑校验也可以解决。

#11 楼 @chinacheng 主要是有个字段被虚拟了。。见我 10 楼回复

引入模块里面的 validate 还不好删,我以前写过这样的代码去掉密码校验

# remove password_digest validator
_validate_callbacks.delete_if {|c| c.raw_filter.is_a?(ActiveModel::Validations::PresenceValidator) && c.raw_filter.attributes.include?(:password_digest)}
_validators.delete(:password_digest)

比较丑,拷贝一份 SecurePassword 模块再修改还比较漂亮。

hmmm, looks like you have unique check for the nickname. take a look whether you have two users with same nickname, and remove one of them.

You need to Sign in before reply, if you don't have an account, please Sign up first.