Schienen: Überprüfen der Aufnahme eines booleschen tests fehlschlägt
Ich versuche, um sicherzustellen, dass ein Feld der mein Modell ist ein boolescher Wert, aber meine tests halten scheitern.
Nach der Lektüre dieses: Validierung boolean Wert in Rspec und Schienen und diese Schienen: wie kann ich überprüfen, ob etwas ist ein boolean? landete ich mache es so:
class Model < ActiveRecord::Base
validates :my_field, :inclusion => { :in => [true, false] }
end
Habe ich versucht, dieses zu testen ein paar verschiedene Möglichkeiten (mit rspec und shoulda Matcher) und da meine tests keep on failing, ich bin jetzt bis auf die dümmste mögliche (?) Weise. Trotzdem, die tests nicht bestehen, und ich vermute, dass es einige-Mechanismus, konvertiert den Wert irgendwo.
Hier ist, was ich verwende, um herauszufinden, was Los ist:
# create instance without setting value ...
# these work as expected
model_instance.valid?.should be_false # passes
model_instance.my_field = true
model_instance.valid?.should be_true # passes
model_instance.my_field = false
model_instance.valid?.should be_true # passes
# works as expected
model_instance.my_field = ""
model_instance.valid?.should be_false # passes
# these should pass but fail
model_instance.my_field = "foo"
model_instance.my_field.should == "foo" # fails as well, my_field == false
model_instance.valid?.should be_false # fails
model_instance.my_field = "false"
model_instance.my_field.should == "false" # fails as well, my_field == false
model_instance.valid?.should be_false # fails
model_instance.my_field = "123"
model_instance.valid?.should be_false # fails
model_instance.my_field = "true"
model_instance.my_field.should == "true" # fails as well, my_field == true
model_instance.valid?.should be_false # fails
Was bin ich?
Scheint der Wert wird umgewandelt in eine einigermaßen logische Art und Weise aber, wo und wie es zu verhindern? Wie das zu tun diese Art der Validierung, richtig?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich weiß nicht, wo diese Idee, die Sie bestätigen müssen ein Feld vom Typ boolean als true/false kamen, aber ich habe gesehen, dass es in ein paar unzusammenhängende Projekte in letzter Zeit, so langsam beginne ich zu Fragen, ob das nicht ein meme, das begann irgendwo.
Seine ein boolean Feld, es MUSS true oder false sein. AR kümmert sich um die details der Implementierung der booleschen Werte für Sie. Wenn Sie möchten, dass ein boolean-Feld erstellen Sie ein Boolesches Feld in der Datenbank. Ende der Geschichte.
Blick auf die Quelle, hier ist der code, konvertiert einen Wert in einen booleschen Wert:
Und hier sind die Werte, die gleich Ihre booleschen Pendants:
Also nehmen einen Blick auf deinen code von oben, alles ist wie es sein sollte, außer, dass das, was Sie erwartet, ist falsch. Zuordnung von "foo" in einen booleschen Wert, den wir sehen, dass "foo" ist nicht in der Liste der akzeptablen wahren Werte, also die boolean-Feld wird standardmäßig auf false, was ist, was wird es wieder aus seiner accessor später. Der Boolesche Wert für das Feld ist immer noch
:in => [true, false]
so dass das Modell gültig ist. "false" und "123" aus dem gleichen Grund scheitern. "true" ist ein akzeptabler Wert des boolean-true, so wird das Feld auf true festgelegt wird und ist immer noch gültig, aus dem Grund wie oben beschrieben.FALSE_VALUES
/TRUE_VALUES
Konstanten. Und deine umfassende Antwort erklärt es sehr schön! Habe heute etwas gelernt.nil
.TRUE_VALUES
entfernt wurde, mit Schienen v5. Schauen Sie sich den neuen code: github.com/rails/rails/commit/...Bin ich kein Rails-guru, aber ich bleibe meinen Hals raus und sagen, dass Sie das unbedingt tun wollen, überprüfen Boolesche Werte für
:inclusion => { :in => [true, false] }
--das heißt, wenn Sie nicht zulassen möchten nil (NULL -) Werte.Kommen aus einer Datenbank Programmierung im hintergrund, ich habe gelernt, zu beachten, dass ein boolean-Feld kann DREI Werte haben: true, false und NULL. Bei der Programmierung native SQL-Null-Werte eine Besondere Behandlung erfordern (
is null
statt= null
), die bewirkt, dass eine Menge zusätzlicher Arbeit.Im Test mit Rails 3.2 heute, war es kein problem zum erstellen einer ungeprüften boolean-Feld mit einem null-Wert ein, und speichern Sie es auf meine PostgreSQL-Datenbank, wo Sie war brav gespeichert als NULL. Um zu vermeiden, alle Probleme, die verursachen würde, ich bin der Planung über die Verwendung dieser Ansatz für Boolesche Werte in Rails:
:null => false
in Migrationen.:inclusion => { :in => [true, false] }
zur Validierung das Feld im Modell. Das gibt eine schöne Nachricht, wenn der Bereich ist nicht initialisiert (null).Ist es nicht intuitiv, dass ich nicht verwenden können, eine
:presence
Validierung, aber es stellt sich heraus:presence
wird überprüft, ob der Wert nicht leer ist, und der Wertfalse
ist leer. In anderen Worten, wenn Sie überprüfen:presence => true
und setzen Sie den Wert auffalse
, die Validierung schlägt fehl. Sehen validates_presence_of in der API und @Paul Jungwirth Kommentar @Karmajunkie Antwort.