我试图确保我的模型的一个字段是一个布尔值,但我的测试继续失败.
看完这个:Validating boolean value in Rspec and Rails和Rails: how do I validate that something is a boolean?我结束了这样做:
class Model < ActiveRecord::Base validates :my_field,:inclusion => { :in => [true,false] } end
我已经尝试了几种不同的方式(使用rspec和应用程序匹配器),并且由于我的测试仍然失败,所以我现在正在以最愚蠢的方式进行测试.仍然,测试不通过,我猜测有一些机制可以将值转换到某处.
以下是我用来了解发生的情况:
# 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
我失踪了什么
似乎有价值的转换是有点逻辑的,但在哪里和如何防止它?如何正确地进行这种验证?
解决方法
我不知道你需要验证一个布尔字段为true / false的想法来自哪里,但是我最近在几个不相关的项目中看到了这一点,所以我开始怀疑这不是一个meme从某处开始
它是一个布尔字段,它是真或假. AR会为您处理布尔值的实现细节.如果您想要一个布尔型字段,请在数据库中创建一个布尔字段.故事结局.
看源码,这里是将值转换为布尔值的代码:
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb,line 147 147: def value_to_boolean(value) 148: if value.is_a?(String) && value.blank? 149: nil 150: else 151: TRUE_VALUES.include?(value) 152: end 153: end
这些值等于他们的布尔对应:
TRUE_VALUES = [true,1,'1','t','T','true','TRUE'].to_set FALSE_VALUES = [false,'0','f','F','false','FALSE'].to_set
所以再看看你上面的代码,一切都是应该的,除了你所期望的是不正确的.将“foo”分配给一个布尔值,我们看到“foo”不在可接受的true值的列表中,所以布尔字段默认为false,这将从它的访问器返回.该字段的布尔值仍为:in => [true,false]所以模型是有效的.同样的原因,“虚假”和“123”失败. “true”是布尔值true的可接受值,因此该字段设置为true,并且由于上述原因仍然有效.