Я столкнулся с той же проблемой, и после прочтения этого поста я применил код, предложенный 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?
(таким образом, проверка не будет выполняться).Поэтому после некоторых испытаний и скорби я обнаружил, что это лучший способ сделать это.