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

lin_style · 2012年09月19日 · 最后由 chentianwen 回复于 2012年09月19日 · 4115 次阅读

# 设置 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 !@user.update_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 !@user.update_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,这不肯定有值吗??

@user.errors打印出来啊

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

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

匿名 #6 2012年09月19日

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.

需要 登录 后方可回复, 如果你还没有账号请 注册新账号