2010-03-02 6 views
37

Ist es generell besser (und warum), Attribute im Modell oder in der Datenbankdefinition zu validieren?Ruby on Rails: Ist es besser, im Modell oder in der Datenbank zu validieren?

Für (triviales) Beispiel:

Im Benutzermodell:

validates_presence_of :name 

im Vergleich zu in der Migration:

t.string :name, :null => false 

Auf der einen Seite, einschließlich dem sie in der Datenbank scheint mehr eine Garantie gegen jede Art von schlechten Daten schleichen sich ein. Auf der anderen Seite, macht es in das Modell ein, macht Dinge transparenter und leichter zu verstehen, indem man es im Code mit dem Rest gruppiert f die Validierungen. Ich habe auch darüber nachgedacht, beides zu tun, aber das scheint sowohl untrocken als auch weniger pflegeleicht zu sein.

Antwort

45

Ich würde es sehr empfehlen, es an beiden Orten zu tun. Wenn Sie dies im Modell tun, ersparen Sie sich eine Datenbankabfrage (möglicherweise über das Netzwerk), die im Wesentlichen fehlschlägt, und das Ausführen in der Datenbank gewährleistet die Datenkonsistenz.

+1

Sie schlagen mich um 20 Sekunden;) – Aurril

+4

Ich stimme mit der Validierung von Einschränkungen an beiden Orten (ich benutze PostgreSQL und die sexy_pg_constraints http://github.com/maxim/sexy_pg_constraints Plugin für diese), aber es ist nicht völlig richtig, dass Wenn Sie Ihre In-Modelle validieren, wird eine Datenbankabfrage gespeichert. Zum Beispiel muss 'validates_uniqueness_of' eine DB-Abfrage durchführen. –

4

Es ist eine gute Übung, beides zu tun. Die Modellvalidierung ist benutzerfreundlich, während die Datenbankvalidierung eine letzte Komponente enthält, die Ihren Code härtet und fehlende Gültigkeitsbereiche in Ihrer Anwendungslogik aufdeckt.

2

Es variiert. Ich denke, dass einfache, datenbezogene Validierung (wie Stringlängen, Feldbedingungen, usw.) in der Datenbank durchgeführt werden sollte. Jede Validierung, die bestimmten Geschäftsregeln folgt, sollte im Modell durchgeführt werden.

0

Abhängig von Ihrer Anwendung Design, Wenn Sie eine kleine oder mittelgroße Anwendung haben Sie entweder kann es in beide tun oder einfach nur in Modell, Aber wenn Sie eine große Anwendung haben wahrscheinlich seine Service-orientierte oder in Schichten dann Grund haben Validierung, dh obligatorisch/nullable, min/max Länge usw. in Datenbank und striktere dh Muster oder Geschäftsregeln in Modell.

11

Und auch

validates_presence_of :name 

nicht gleich

t.string :name, :null => false 

Wenn Sie nur NOT NULL Spalte in der DB gesetzt noch Sie Blindwert eingeben (""). Wenn Sie das Modell validates_presence_of verwenden, können Sie dies nicht tun.

+1

Guter Fang, danke. Werde ich blind, oder gibt es wirklich keine vorvalidierte validates_not_nil, um die Modelllogik an die Datenbanklogik anzupassen, wie es alle empfohlen haben? –

1

Ich würde Migration Validators Projekt (https://rubygems.org/gems/mv-core) empfehlen, um die Validierung auf db-Ebene zu definieren und sie dann transparent auf das ActiveRecord-Modell zu übertragen.

Beispiel:

in der Migration:

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

in Ihrem Modell:

class Post < ActiveRecord::Base 
    enforce_migration_validations 
end 

Wie führen Sie zwei Ebenen Datenvalidierung haben. Der erste wird in db implementiert (als Bedingung für die Auslösung der Check-Bedingung) und der zweite als ActiveModel-Validierung in Ihrem Modell.