2016-01-13 20 views
8

Gibt es irgendwelche Vorteile bei Validierungen für boolesche Felder von Modellen?Boolesches Feld validieren oder nicht validieren

hatte ich eine Bestätigung für das Vorhandensein eines boolean Feldes sicherzustellen

validates :boolean_attribute, presence: true 

Es scheiterte, als boolean_attribute falsch war. Ich googelte herum und fand diese SO Fragen in Bezug auf das Thema.

Rails database defaults and model validation for Boolean fields
Rails validates_presence not validating on Boolean?

hinzugefügt Dann diese Validierung statt

validates :field, :inclusion => {:in => [true, false]} 

Das machte mich denken. Brauche ich irgendwelche Validierungen für boolsche Felder? Sein Wert wird immer wahr oder falsch oder nicht wahr sein? Selbst wenn jemand böswillig versucht, es zu ändern, um eine Zahl zu sagen, würde sich der Typ nicht darum kümmern? Oder gibt es eine Sicherheit, die die obige Einschlussvalidierung bietet?

+0

ja, stört mich normalerweise nicht. Wenn das Feld obligatorisch ist, können Sie den obigen Inklusionstrick verwenden und sicherstellen, dass "null: false" in die Spalte –

+0

gesetzt wird. Wenn Sie den Wert "true" oder "false" benötigen, aber nicht "nil", dann Sie möchten die Validierung verwenden. Wenn 'true',' false' und 'nil' in Ordnung sind, brauchen Sie die Validierung nicht. Welche davon für Sie richtig ist, hängt ganz von Ihrem Anwendungsfall ab. –

+0

@ Jordan: Ich bin cool mit Null, solange Ruby es auf falsch validiert und es gibt keine Szenarien, die das System brechen könnten. Sind da irgendwelche? –

Antwort

8

Ob Sie ein boolesches Attribut für die Aufnahme in [ true, false ] validieren sollten, hängt vollständig von Ihrem Anwendungsfall ab.

Sie haben richtig erkannt, dass in der Abwesenheit der Validierung anderen Code, ein boolesches Feld in Rails wird es immer sein (nach Art Zwang) true, false oder nil. Schienen werden nil zu false nicht zwingen. Wenn Sie das boolesche Attribut eines Modells auf nil setzen und es speichern, lautet das Attribut nil, nicht false, wenn Sie es später aus der Datenbank abrufen.

Sie können sich nil als einen "dritten Zustand" für ein boolesches Feld vorstellen. Betrachten Sie eine einfache Umfrage-App, mit der Benutzer eine nicht abgeschlossene Umfrage speichern können, um sie später abzuschließen. Angenommen, ein Benutzer speichert eine unvollständige Umfrage mit der Frage "Isst du Fleisch?" unbeantwortet. Sie möchten false nicht in der Datenbank speichern, da dies anzeigen würde, dass der Benutzer mit "Nein" geantwortet hat. Wenn der Benutzer zurückkehrt, um die Umfrage zu beenden, möchten Sie, dass diese Frage immer noch unbeantwortet ist. Sie möchten also nil in der Datenbank speichern.

In Fällen wie oben ist es angemessen (und notwendig) nicht für die Aufnahme in [ true, false ] zu validieren.

Als Faustregel würde ich jedoch sagen, dass in allen anderen Fällen - d. In jedem Fall, in dem Sie keine Werte für nil haben, sollten Sie boolesche Felder für die Aufnahme in [ true, false ] validieren.

Natürlich, wenn Sie tun erlauben nil Sie brauchen, vorsichtig zu sein, weil, wie Sie wissen, nil ein in Ruby Falsey Wert ist. Sie müssen explizit nach "Nilness" an Orten suchen, an denen Sie sich sonst auf die Wahrheit oder Falschheit eines Wertes verlassen könnten. Das heißt, statt dies:

if !is_meat_eater 
    unanswered_questions << :is_meat_eater 
end 

..., die wie beabsichtigt nicht benehmen, wenn is_meat_eaterfalse ist, müssen Sie explizit für nil überprüfen:

if is_meat_eater.nil? 
    unanswered_questions << :is_meat_eater 
end 
+0

Danke @ Jordan +1 für das Szenario. –

+0

upvoted für die Mühe :) –

0

Wenn Sie echte Typ-Validierung wollen, würde ich sagen, überprüfen Sie die validates_type Edelstein. Es wird die Validierung für Ihr Attribut vor Art der Nötigung durchführen. Typenzerzwingung kann ein unerwartetes Verhalten haben, this answer zeigt, wie nur eine bestimmte Menge von Werten "truthy" ist.

Wenn Sie eine zu nil akzeptieren, ist das nicht wirklich ein Recht? Das ist entweder true, false oder ein dritter Wert, nil.

4

Sie brauchen nicht um ein boolean Feld zu validieren, wenn es nicht wahr ist, ist es falsch.

Nur set a "default" in your db, so dass der Bool wird immer ganz gleich einen bestimmten Wert haben, was:

#db/migrate/add_boolean_column_______.rb 
class AddBooleanColumn < ActiveRecord::Migration 
    def change 
     change_table :table do |t| 
     t.boolean :field, default: false 
     end 
    end 
end 

Auf diese Weise habe ich nicht einmal alle Validierungen umfassen würde. Das System stellt sicher, dass Sie es entweder als wahr oder falsch festlegen - was Ihnen als Entwickler überlassen bleibt.