8

Tôi đang cố gắng đặt chương trình của mình để mật khẩu chỉ được xác thực nếu nó được thay đổi (để người dùng có thể chỉnh sửa thông tin khác mà không cần phải nhập mật khẩu của họ).Phương thức chưa xác định password_changed? Lỗi

tôi hiện đang nhận được một lỗi nói rằng

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

khi tôi cố gắng đăng nhập

Đây là mã xác nhận của tôi trong 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? 

Đây là phương pháp tạo của tôi trong 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 

Cảm ơn bạn!

Trả lời

5

Replace with:

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

Tôi muốn làm hai kiểm chứng thực khác nhau:

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? } 
+0

Không, vẫn gặp lỗi tương tự. – steffi2392

+1

là 'mật khẩu' một cột của mô hình của bạn? – apneadiving

+0

trong cơ sở dữ liệu? Không, chỉ là encrypted_password. Tôi có nên thêm nó? – steffi2392

3

tôi gặp phải vấn đề này cùng và sau khi đọc bài này tôi thực hiện các mã được đề xuất bởi apneadiving trong câu trả lời của anh ấy nhưng với một sửa đổi nhỏ:

Tôi đã sử dụng hai xác thực khác nhau, một f hoặc tạo:

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

và sau đó tôi sử dụng cái này để cập nhật:

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

Ban đầu, tôi thực hiện chính xác những gì apneadiving đề nghị, nhưng tôi nhận ra rằng trên bản cập nhật cho người dùng nó không thực sự xác nhận sự hiện diện của một chuỗi. Như trong, nó cho phép người dùng đặt mật khẩu của họ thành " " (Một chuỗi các khoảng trắng). Điều này là do thực tế là " ".blank? == true, và vì vậy nếu bạn có nó thiết lập để xác nhận như thế này:

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

Sau đó, nó sẽ không chạy xác nhận nếu một chuỗi đầy đủ các khoảng trắng được gửi bởi người dùng sẽ được đệ trình bởi vì nó đọc chuỗi là trống. Điều này về cơ bản làm mất hiệu lực của việc xác thực cho sự hiện diện trên bản cập nhật. Lý do tôi làm password.to_s.empty? thay vì chỉ đơn giản là password.empty? là để ngăn chặn lỗi nếu ai đó gọi update_attributes trên mô hình người dùng và không chuyển bất kỳ thứ gì vào mật khẩu, trường thì mật khẩu sẽ là nil và vì lớp ruby ​​nil không có một sản phẩm nào? phương pháp, nó sẽ ném một lỗi. Gọi số .to_s trên nil, tuy nhiên sẽ chuyển đổi nó thành một chuỗi trống, chuỗi này sẽ trả về giá trị thực trong một cuộc gọi liên tiếp .empty? (do đó việc xác thực sẽ không chạy). Vì vậy, sau một số thử nghiệm và hoạn nạn, tôi thấy rằng đây là cách tốt nhất để làm điều đó.

1

Thay đổi để tìm kiếm, trong Rails 4 ít nhất, là 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 
+0

Điều này đã khắc phục sự cố cho tôi, cảm ơn bạn! – IGNIS

+0

Tương tự như vậy, không có điều nào ở trên phù hợp với tôi. Tôi đã kết thúc với điều này thay vào đó, chỉ trong trường hợp: 'validates_presence_of: password_confirmation, if: lambda {| staff | staff.password.present? } ' Vì vậy, bây giờ nó yêu cầu password_confirmation trên cả hai tạo và cập nhật, và chỉ khi có một thuộc tính mật khẩu được gửi là tốt. Tôi ngạc nhiên đây không phải là hành vi mặc định. –

1

Đã kết thúc ở đây googling thông báo lỗi này, và sử dụng

@account.encrypted_password_changed?

trong trường hợp của tôi mang lại những gì tôi muốn.