Rails: проверка только при создании или при обновлении, когда поле не пустое

Как я могу ограничить проверку Rails проверять только при создании OR, когда поле не пустое? Я создаю страницу настроек пользователя для приложения, над которым я работаю, и проблема заключается в том, что при обновлении с использованием параметров, предоставляемых формой, настройки сохраняются только при наличии пароля и подтверждения пароля. Я бы хотел, чтобы эти поля пароля проверялись при создании независимо от того, что, но только при обновлении, когда они предоставляются.

Ответ 1

Это оказалось немного проще, чем я думал. Я изменил имена ввода формы с password и password_confirmation на new_password и new_password_confirmation. Я добавил временные аксессоры для этих значений в моей модели, используя следующую строку:

attr_accessor :new_password, :new_password_confirmation

Я реализовал password_changed? метод, определяемый следующим образом:

def password_changed?
    !new_password.blank?
end

Наконец, я изменил свои проверки на:

validates :new_password, presence: true, confirmation: true, length: { in: 6..20 }, on: :create
validates :new_password, presence: true, confirmation: true, length: { in: 6..20 }, on: :update, if: :password_changed?
validates :new_password_confirmation, presence: true, on: :create
validates :new_password_confirmation, presence: true, on: :update, if: :password_changed?

Я уверен, что лучший способ сделать это (это не очень СУХОЙ), но пока это работает. Улучшенные ответы по-прежнему будут очень оценены.

Ответ 2

Если вы хотите разрешить пустые значения, используйте: allow_blank с проверками.

class Topic < ActiveRecord::Base
  validates :title, length: { is: 5 }, allow_blank: true
end

Если вы хотите проверить только создавать, использовать на с Подтверждает.

class Topic < ActiveRecord::Base
  validates :email, uniqueness: true, on: :create
end

Чтобы покрыть ваше дело:

class Topic
  validates :email, presence: true, if: :should_validate?

  def should_validate?
    new_record? || email.present?
  end
end

Ответ 3

Пожалуйста попробуйте

validates :<attributes>, if: Proc.new{|obj| obj.new_record? || !obj.<attribute>.blank? }

или добавить собственные имена методов вместо имени атрибута.

Ответ 4

Не нужно менять имена полей, будет достаточно, чтобы заменить :password_changed? to :password_digest_changed? в вашем коде.

validates :password, presence: true, confirmation: true, length: { in: 6..20 }, on: :create
validates :password, presence: true, confirmation: true, length: { in: 6..20 }, on: :update, if: :password_digest_changed?
validates :password_confirmation, presence: true, on: :create
validates :password_confirmation, presence: true, on: :update, if: :password_digest_changed?