Неопределенный метод password_changed?ошибка - PullRequest
8 голосов
/ 16 августа 2011

Я пытаюсь настроить свою программу так, чтобы пароль действовал только в случае его изменения (чтобы пользователь мог редактировать другую информацию, не вводя свой пароль).

В настоящее время я получаю сообщение об ошибке

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 ]

5 голосов
/ 16 августа 2011

Заменить на:

: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? }  
3 голосов
/ 14 октября 2011

Я столкнулся с той же проблемой, и после прочтения этого поста я применил код, предложенный 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? }

Изначально я реализовал именно то, что предлагал апноэ, но я понял, что при обновлениях для пользователя это на самом деле не проверяет наличиестрока.Например, он позволял пользователю устанавливать свой пароль на " " (строка пробела).Это связано с тем, что " ".blank? == true, и поэтому, если он настроен для проверки следующим образом:

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

Тогда проверка не будет выполняться, если строка, заполненная пробелами, переданаПользователь отправлен, потому что он читает строку как пустую.По сути, это делает недействительным эффект проверки наличия на обновлении.Причина, по которой я сделал password.to_s.empty? вместо простого password.empty?, состоит в том, чтобы предотвратить ошибки, если кто-то вызывает update_attributes для модели пользователя и ничего не передает в поле пароля, тогда пароль будет nil, и, посколькуruby nil в классе нет пустых?метод, он выдаст ошибку.Вызов .to_s для nil, однако, преобразует ее в пустую строку, которая будет возвращать true при последующем вызове .empty? (таким образом, проверка не будет выполняться).Поэтому после некоторых испытаний и скорби я обнаружил, что это лучший способ сделать это.

2 голосов
/ 04 ноября 2015

Заканчивается здесь, прибегая к поиску этого сообщения об ошибке и используя

@account.encrypted_password_changed?

в моем случае дал то, что я хотел.

1 голос
/ 18 июля 2015

Изменение, которое нужно искать, по крайней мере в 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
...