8

我正在尝试设置我的程序,以便仅在更改密码时验证密码(因此用户可以编辑其他信息而无需输入密码)。

我目前收到一条错误消息

NoMethodError in UsersController#create, undefined method `password_changed?' for #<User:0x00000100d1d7a0>

当我尝试登录时。

这是我的验证代码user.rb

    validates :name,  :presence => true,
 :length   => { :maximum => 50 }
validates :email, :presence   => true,
:format     => { :with => email_regex },
:uniqueness => { :case_sensitive => false }
validates :password, :presence =>true, :confirmation => true, :length => { :within => 6..40 }, :if=>:password_changed?  

这是我的创建方法users_controller.rb

def create
    @user = User.new(params[:user])
    if @user.save
        sign_in @user
        flash[:success] = "Welcome to the Sample App!"
        redirect_to @user
    else
        @title = "Sign up"
        render 'new'
    end
end

谢谢!

4

4 回答 4

5

用。。。来代替:

:if => lambda {|user| user.password_changed? }

我会做两个不同的验证:

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? }  
于 2011-08-16T15:40:47.667 回答
3

我遇到了同样的问题,在阅读了这篇文章后,我实现了 apneadiving 在他的回答中建议的代码,但稍作修改:

我使用了两种不同的验证,一种用于创建:

validates :password, :presence => true, :confirmation => true, :length => { :within => 6..128 }, :on => :create

然后我用这个进行更新:

validates :password, :presence => true, :confirmation => true, :length => { :within => 6..128 }, :on => :update, :unless => lambda{ |user| user.password.to_s.empty? }

最初,我完全实现了 apneadiving 的建议,但我意识到在对用户进行更新时,它实际上并没有验证字符串的存在。如,它允许用户将他们的密码设置为" "(一串空格)。这是由于" ".blank? == true, 因此如果您将其设置为像这样进行验证:

:unless => lambda { |user| user.password.blank? }

如果用户提交了一个充满空格的字符串,则它不会运行验证,因为它将字符串读取为空白。这实质上使验证存在对更新的影响无效。我这样做的原因password.to_s.empty?不仅仅是password.empty?为了防止错误,如果有人在用户模型上调用 update_attributes 并且没有将任何内容传递到密码字段中,那么密码将为nil,并且由于 rubynil​​ 类没有空?方法,它会抛出一个错误。但是,调用.to_sonnil会将其转换为空字符串,这将在连续.empty?调用时返回 true (因此验证不会运行)。所以经过一些考验和磨难后,我发现这是最好的方法。

于 2011-10-14T18:19:55.377 回答
2

在这里结束了谷歌搜索此错误消息,并使用

@account.encrypted_password_changed?

在我的情况下产生了我想要的。

于 2015-11-04T04:24:53.760 回答
1

至少在 Rails 4 中要寻找的变化是password_digest.

@account.password = "my new password"
@account.changes # => {"password_digest"=>["$2a$10$nR./uTAmcO0CmUSd5xOP2OMf8n7/vXuMD6EAgvCIsnoJDMpOzYzsa", "$2a$10$pVM18wPMzkyH5zQBvcf6ruJry22Yn8w7BrJ4U78o08eU/GMIqQUBW"]}
@account.password_digest_changed? # => true
于 2015-07-17T23:48:30.027 回答