Rails проверяет, что password_confirmation присутствует, когда пароль также присутствует или был изменен - PullRequest
6 голосов
/ 23 октября 2011

У меня есть следующая модель пользователя:

class User < ActiveRecord::Base
  # Users table has the necessary password_digest field
  has_secure_password
  attr_accessible :login_name, :password, :password_confirmation

  validates :login_name, :presence=>true, :uniqueness=>true

  # I run this validation on :create so that user 
  # can edit login_name without having to enter password      
  validates :password,:presence=>true,:length=>{:minimum=>6},:on=>:create

  # this should only run if the password has changed
  validates :password_confirmation, 
            :presence=>true, :if => :password_digest_changed?
end

Эти проверки не совсем то, что я надеялся. Можно сделать следующее:

# rails console
u = User.new :login_name=>"stephen"
u.valid? 
# => false
u.errors 
# => :password_digest=>["can't be blank"], 
# => :password=>["can't be blank", "please enter at least 6 characters"]}

# so far so good, let's give it a password and a valid confirmation
u.password="password"
u.password_confirmation="password"

# at this point the record is valid and does save
u.save
# => true

# but we can now submit a blank password from console
u.password=""
# => true
u.password_confirmation=""
# => true

u.save
# => true
# oh noes

Итак, я хочу следующее:

  • пароль, необходимый при создании, должен состоять из 6 символов в длину
  • пароль_подтверждение требуется при создании, должен совпадать с паролем
  • пользователь не должен указывать пароль при обновлении имени_ логина
  • пароль нельзя удалить при обновлении

Что меня смущает, так это то, что rails выдает ошибку no method , если я использую password_changed? вместо :password_digest_changed? в моей проверке пароля_подтверждения. Я не понимаю почему.

Так кто-нибудь знает, что я здесь не так делаю?

1 Ответ

13 голосов
/ 23 октября 2011

password не столбец в базе данных, верно?Просто атрибут?

Так что нет метода password_changed?, который был бы доступен, если бы password был столбцом.Скорее вам следует просто проверить, установлено ли значение password.

Что-то вроде:

validates :password_confirmation, :presence => true, :if => '!password.nil?'

Хотя это решает первоначальную проблему, с которой вы столкнулись, это все равно не совсемделайте что хотите, так как это только проверка присутствия, и вам нужно, чтобы присутствовали и совпадают с паролем.Должно работать что-то вроде следующего (в сочетании с вышеупомянутой проверкой).

validates :password, 
          # you only need presence on create
          :presence => { :on => :create },
          # allow_nil for length (presence will handle it on create)
          :length   => { :minimum => 6, :allow_nil => true },
          # and use confirmation to ensure they always match
          :confirmation => true

Если вы никогда не видели :confirmation раньше, это стандартная проверка, которая ищет foo и foo_confirmation иудостоверяется, что они одинаковы

Обратите внимание, что вам все равно нужно проверить наличие password_confirmation

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...