web-dev-qa-db-fra.com

Rails: valider uniquement lors de la création ou de la mise à jour lorsque le champ n'est pas vide

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.

26
Jamie

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.

12
Jamie

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
45
cristian

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?
7
Anton Ruban

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.

6
Sanket