2010-03-02 3 views
37

Est-il généralement préférable (et pourquoi) de valider les attributs dans le modèle ou dans la définition de la base de données?Ruby on Rails: Vaut-il mieux valider dans le modèle ou la base de données?

Pour (un trivial) exemple:

Dans le modèle utilisateur:

validates_presence_of :name 

par rapport à la migration:

t.string :name, :null => false 

D'une part, y compris dans la base de données semble D'autre part, l'inclure dans le modèle rend les choses plus transparentes et plus faciles à comprendre en les regroupant dans le code avec le reste. f les validations. J'ai également envisagé de faire les deux, mais cela semble à la fois non-DRY et moins maintenable.

Répondre

45

Je recommande fortement de le faire dans les deux endroits. Le faire dans le modèle vous permet d'économiser une requête de base de données (éventuellement à travers le réseau) qui sera essentiellement une erreur, et le faire dans la base de données garantit la cohérence des données.

+1

Vous me battez en 20 secondes;) – Aurril

+4

Je suis d'accord avec les contraintes de validation dans les deux endroits (j'utilise PostgreSQL et le plugin sexy_pg_constraints http://github.com/maxim/sexy_pg_constraints pour cela) mais il n'est pas totalement vrai que valider votre dans les modèles permettra d'enregistrer une requête DB. Par exemple, 'validates_uniqueness_of' doit faire une requête DB. –

4

Il est recommandé de faire les deux. La validation de modèle est conviviale tandis que la validation de base de données ajoute un composant de dernier recours qui durcit votre code et révèle des validations manquantes dans votre logique applicative.

2

Cela varie. Je pense que cette validation simple, liée aux données (telles que les longueurs de chaînes, les contraintes de champs, etc ...) devrait être faite dans la base de données. Toute validation qui suit certaines règles métier doit être effectuée dans le modèle.

0

dépend de votre conception de l'application, Si vous avez une petite ou une application de taille moyenne, vous pouvez le faire dans les deux ou tout simplement dans le modèle, Mais si vous avez une grande demande probablement son service orienté ou en couches ont alors de base validation ie obligatoire/nullable, longueur min/max etc. dans la base de données et plus strict c'est-à-dire les règles ou les règles métier dans le modèle.

11

Et aussi

validates_presence_of :name 

pas le même

t.string :name, :null => false 

Si vous venez de colonne NOT NULL, dans votre DB, vous pouvez toujours insérer la valeur vide (""). Si vous utilisez le modèle validates_presence_of, vous ne pouvez pas.

+1

Bonne prise, merci. Est-ce que je deviens aveugle, ou est-ce qu'il n'y a pas vraiment de validates_not_nil pré-chargé de mettre dans la logique du modèle pour correspondre à la logique de base de données comme tout le monde l'a recommandé? –

1

Je recommanderais le projet Migration Validators (https://rubygems.org/gems/mv-core) pour définir la validation au niveau de la base de données, puis la promouvoir de manière transparente dans le modèle ActiveRecord.

Exemple:

migration:

def change 
    create_table :posts do |t| 
    t.string :title, length: 1..30 
    end 
end 

dans votre modèle:

class Post < ActiveRecord::Base 
    enforce_migration_validations 
end 

Comme résultat, vous aurez la validation des données à deux niveaux. Le premier sera implémenté dans db (en condition de déclenchement de la contrainte check) et le second en validation ActiveModel dans votre modèle.

Questions connexes