Comprendre les validations ActiveRecord Ruby on Rails

Les données sont une excellente chose, mais les mauvaises données peuvent être très très mauvaises. Heureusement, si vous êtes un programmeur Ruby on Rails, vous avez une belle API d’assistants de validation ActiveRecord à votre disposition.

Ce guide est une exploration des validations ActiveRecord courantes et moins courantes dans une application Ruby on Rails donnée. Utilisez-le pour aider à garder vos bases de données heureuses!

Pourquoi utiliser des validations ?

Pour vous assurer que seules les données valides sont enregistrées dans votre base de données. En plus de la validation côté client, les validations au niveau du modèle fournissent une couche de sécurité supplémentaire pour tous les champs de formulaire d’une application Ruby on Rails.

Vous pouvez fournir des validations dans une variété de niveaux, mais tous ont leurs forces et leurs faiblesses.

  • Contraintes de base de données – Les contraintes uniques au niveau de la base de données ne permettent pas de champs ou de colonnes en double si vous en avez besoin. Cela peut aller beaucoup plus loin que l’unicité. c’est-à-dire les valeurs par défaut, les contraintes non nulles, les plages, etc…
  • Validation côté client – Elles sont utiles visuellement et offrent une meilleure expérience utilisateur, mais sont souvent plus peu fiables. Je fournirais presque toujours un plan de sauvegarde en utilisant cette approche comme il se doit.
  • Niveau du modèle (Rails) – De quoi nous parlons maintenant!
  • Niveau de contrôleur (Rails) – Tentant à utiliser mais plus difficile à tester et à entretenir. C’est une convention / une bonne pratique pour garder vos contrôleurs aussi légers que possible.

Quand la validation se produit-elle réellement ?

Directement depuis la documentation ruby on rails:

Il existe deux types d’objets d’enregistrement actifs : ceux qui correspondent à une ligne dans votre base de données et ceux qui ne le font pas. Lorsque vous créez un nouvel objet, par exemple en utilisant la méthode new, cet objet n’appartient pas encore à la base de données. Une fois que vous appelez save sur cet objet, il sera enregistré dans la table de base de données appropriée. L’enregistrement actif utilise la méthode d’instance new_record? pour déterminer si un objet est déjà dans la base de données ou non.

La création d’une nouvelle classe d’enregistrement actif nous donne la possibilité d’utiliser une méthode new_record? pour comprendre tout cela.

class Article < ApplicationRecordend

Ce faisant, nous pouvons frapper rails console pour identifier le processus.

$ rails console>> article = Article.new(title: "My Article")=> #<Article id:nil title: "My Article", created_at: nil, updated_at: nil>>> article.new_record?=> true>> article.save=> true>> article.new_record?=> false

Appeler réellement save est ce qui le valide dans la base de données et crée en coulisses les instructions SQL nécessaires pour le faire. En conséquence, les validations sont généralement exécutées avant l’envoi complet des données à la base de données.

Les méthodes suivantes déclenchent des validations lors de l’utilisation :

  • create
  • create!
  • save
  • save!
  • update
  • update!

Les versions bang (par exemple save!) déclenche une exception si l’enregistrement n’est pas valide. Les versions non-bang ne le font pas: save et update renvoie false, et create renvoie simplement l’objet.

Les méthodes qui ignorent les validations

Utilisant l’une des méthodes suivantes ignoreront entièrement les validations. Utilisez avec prudence les données précieuses!

  • decrement!
  • decrement_counter
  • increment!
  • increment_counter
  • toggle!
  • touch
  • update_all
  • update_attribute
  • update_column
  • update_columns
  • update_counters

Validation helpers

What I love about Ruby on Rails is the bundled goodness you get for doing pretty hard things. Les aides à la validation sont l’une de ces choses qui me font me sentir au chaud et à l’aise lorsque je déploie une nouvelle application dans la nature. Cela fournit beaucoup de support pour une large gamme de données que vous collectez peut-être du côté client.

Chaque assistant accepte une option :on et :message. Ces options définissent quand la validation doit être exécutée et quel message doit être ajouté à une collection errors en cas d’échec (vous pouvez les utiliser pour aider à injecter ce qui ne va pas dans vos vues afin que l’utilisateur sache quoi changer / modifier).

Il y a une tonne d’aides à la validation, voici quelques-unes de mes plus utilisées. Veuillez consulter le guide sur les validations d’enregistrements actifs pour plus de cas d’utilisation.

Confirmation

Utile pour valider lorsque deux champs de texte doivent avoir la même entrée. Pensez à une confirmation par e-mail par exemple.

class User < ApplicationRecord validates :email, confirmation: trueend

Maintenant, dans votre vue, vous pouvez avoir deux champs:

<%= text_field :user, :email %><%= text_field :user, :email_confirmation %>

Un point positif ici est que cette validation ne s’effectue que si l’option presence est également définie sur true dans le modèle.

Ainsi, le modèle User reçoit une mise à jour:

class User < ApplicationRecord validates :email, confirmation: true validates :email_confirmation, presence: true end

Exclusion

Si vous devez réserver des mots ou vous assurer qu’une entrée donnée est unique, utilisez exclusion.

class Profile < ApplicationRecord validates :username, exclusion: { in: %w(username1 username2 username3), message: "%{value} has already been taken." }end

Remarquez comment j’ai utilisé :message ici aussi. Ceci est fourni sur tous les assistants de validation.

Vous pouvez également utiliser inclusion de la manière opposée. Voir les documents pour plus d’informations!

Format

Les chaînes de formatage sont parfois idéales pour votre application. Vous pouvez utiliser des expressions régulières dans les validations pour modifier ce que vous recherchez.

class Plan < ApplicationRecord validates :plan_type, format: { with: /\A+\z/, message: "Plans can only inlude letters"}end

Length

J’utilise celui-ci tout le temps pour mettre une contrainte sur la longueur des caractères d’un champ donné.

class User < ApplicationRecord validates :name, length: { minimum: 5 } # sets a minimum validates :bio, length: { maximum: 500 } # sets a maximum validates :handle, length: { in: 5..16 } # provide a rangeend

N’hésitez pas à personnaliser les messages avec :message ici aussi. Les éléments suivants sont tous disponibles pour personnaliser le message.

  • wrong_length
  • too_long
  • too_short

Exemple

class User < ApplicationRecord validates :bio, length: { maximum: 800, too_long: "%{count} characters is the maximum." }end

Presence

C’est probablement l’aide la plus utilisée dans mon sac à outils. La présence vérifie que les champs ne sont pas vides.

class User < ApplicationRecord validates :name, :email, presence: trueend

Vous pouvez également tester l’existence d’une association sur les modèles

class Article < ApplicationRecord belongs_to :user validates :user, presence: true # looks for a user_id field on the articleend

Sur le modèle opposé, vous pouvez faire de même avec un catch appelé inverse_of

class User < ApplicationRecord has_many :articles, inverse_of: :userend

Unicité

Peut-être voulez-vous des noms d’utilisateur uniques sur votre application? L’unicité aide à cela.

class User < ApplicationRecord validates :username, uniqueness: true, { message: "Username already taken" }end

Cela recherche en fait la table User pour les enregistrements existants afin de déterminer uniqueness

Vous pouvez aller plus loin et limiter le uniquenessjusqu’à un scope.

class User < ApplicationRecord validates :plan, uniqueness: { scope: :year, message: "can only update one per year"}end

Validations conditionnelles

Parfois, il suffit de valider dans des conditions données. Vous pouvez effectuer des conditions en utilisant une approche comme celle-ci.

class Purchase < ApplicationRecord validates :card_number, presence: true, if: :paid_with_card? def paid_with_card? payment_type == "card" endend

Besoin de regrouper plusieurs conditions? Vous pouvez le faire

class User < ApplicationRecord with_options if: :is_admin? do |admin| admin.validates :location, length: { minimum: 10 } admin.validates :job_title, presence: true endend

Méthodes personnalisées

Parfois, les aides ne suffisent pas et vous pourriez avoir besoin de quelque chose de plus personnalisé. Vous pouvez créer vos propres méthodes qui font des validations que vous roulez vous-même.

class Invoice < ApplicationRecord validate :active_subscriber, on: :create def active_customer errors.add(:customer_id, "is not active") unless subscriber.active? endend

Notez ici que je valide cette méthode en utilisant l’option :on qui vous permet de déterminer où initialiser la validation. Dans ce cas, j’ai choisi :create.

Vous pouvez également vous connecter à la collection errors car je dois modifier les sorties côté client si vous en avez besoin. Nous n’avons pas le :message sur les méthodes personnalisées dans ce cas. En savoir plus sur les erreurs.

Mots finaux

Espérons que les validations vous ont ouvert des idées pour rendre votre application plus contrainte (dans le bon sens). L’utilisation de Ruby on Rails et de toutes ses facettes permet d’entrer des données sécurisées dans n’importe quelle base de données de votre choix. Des jetons CSRF aux validations au niveau de la base de données, il existe d’innombrables façons d’améliorer votre application pour rester calme quant aux données entrant.

Prise éhontée!

Si vous avez aimé ce post, j’ai plus de vidéos sur YouTube et ici sur mon blog. Vous voulez plus de contenu comme celui-ci dans votre boîte de réception? Abonnez-vous à ma newsletter et recevez-la automatiquement.

Consultez mon cours

https://i.imgur.com/KIaaJEB.jpg

Want Vous voulez apprendre Ruby on Rails à partir de zéro? Découvrez mon prochain cours appelé Hello Rails.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.