Comment puis-je restreindre une validation Rails pour vérifier uniquement lors de la création OR lorsque le champ n'est pas vide? Je crée une page de paramètres utilisateur pour une application) Je travaille et le problème est que, lors de la mise à jour à l'aide des paramètres fournis par le formulaire, les paramètres ne seront enregistrés que lorsqu'un mot de passe et une confirmation de mot de passe sont présents. J'aimerais que ces champs de mot de passe soient validés lors de la création, peu importe quoi, mais uniquement à jour quand ils sont fournis.
Cela s'est avéré être un peu plus simple que je ne le pensais. J'ai changé les noms d'entrée de formulaire de password
et password_confirmation
à new_password
et new_password_confirmation
. J'ai ajouté des accesseurs temporaires pour ces valeurs dans mon modèle en utilisant la ligne suivante:
attr_accessor :new_password, :new_password_confirmation
J'ai implémenté un password_changed?
méthode définie comme suit:
def password_changed?
!new_password.blank?
end
Enfin, j'ai changé mes validations en:
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?
Je suis certain qu'il existe une meilleure façon de le faire (ce n'est pas très sec) mais pour l'instant, cela fonctionne. De meilleures réponses seraient toujours très appréciées.
Si vous souhaitez autoriser les valeurs vides, utilisez: allow_blank with validates.
class Topic < ActiveRecord::Base
validates :title, length: { is: 5 }, allow_blank: true
end
Si vous souhaitez valider uniquement lors de la création, utilisez on avec validates.
class Topic < ActiveRecord::Base
validates :email, uniqueness: true, on: :create
end
Pour couvrir votre cas:
class Topic
validates :email, presence: true, if: :should_validate?
def should_validate?
new_record? || email.present?
end
end
N'est pas nécessaire de changer les noms de champs, sera suffisant pour remplacer :password_changed?
à :password_digest_changed?
dans votre code.
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?
S'il vous plaît essayez
validates :<attributes>, if: Proc.new{|obj| obj.new_record? || !obj.<attribute>.blank? }
ou ajoutez des noms de méthode personnalisés au lieu du nom d'attribut.