Rails:validation包含布尔失败测试

我试图确保我的模型的一个字段是一个布尔值,但我的测试继续失败。

阅读本文后: validationRspec和Rails中的布尔值以及此Rails:如何validation某些内容是否为布尔值? 我最终这样做:

class Model  { :in => [true, false] } end 

我尝试过几种不同的测试方式(使用rspec和shoulda匹配器),而且由于我的测试一直在失败,我现在正在采用最愚蠢的方式(?)。 仍然,测试没有通过,我猜测有一些机制可以在某处转换价值。

以下是我用来了解发生了什么的事情:

 # 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 

我错过了什么? 似乎价值是以某种逻辑方式转换但是在哪里以及如何防止它? 如何正确地进行这种validation?

我不知道你需要将这个想法validation一个布尔字段为真/假来自哪里,但我最近在一些不相关的项目中看到了它,所以我开始怀疑这不是一个模因从某处开始。

它是一个布尔字段,它必须是真或假。 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, '0', 'f', 'F', 'false', 'FALSE'].to_set 

所以再看看上面的代码,除了你所期望的不正确外,一切都应该如此。 将“foo”赋给布尔值我们看到“foo”不在可接受的真值列表中,因此布尔字段默认为false,这是它稍后将从其访问器返回的值。 该字段的布尔值仍为:in => [true, false]因此模型有效。 出于同样的原因,“假”和“123”失败。 “true”是布尔值true的可接受值,因此该字段设置为true,并且由于上述原因仍然有效。

我不是Rails大师,但我会把我的脖子伸到这里说你绝对想要validation布尔值:inclusion => { :in => [true, false] } – 也就是假设你做的不想允许nil(NULL)值。

来自数据库编程背景,我已经学会记住布尔字段可以有三个值:true,false和NULL。 在本机SQL中编程时,NULL需要特殊处理( is null而不是= null ),这会导致大量额外工作。

在今天使用Rails 3.2进行测试时,创建一个带有nil值的未经validation的布尔字段并将其保存到我的PostgreSQL数据库是没有问题的,它将其尽职地存储为NULL。 为了避免可能导致的所有问题,我打算在Rails中使用这种方法来处理布尔值:

  • 在迁移中使用:null => false定义布尔字段。
  • 使用:inclusion => { :in => [true, false] }来validation模型中的字段。 如果字段未初始化(nil),这会给出一个很好的消息。

一开始并不直观,我不能使用:presencevalidation,但事实certificate:presencevalidation值不是空白,值false 空。 换句话说,如果validation:presence => true并将值设置为false ,则validation将失败。 请参阅API中的validates_presence_of和@Paul A Jungwirth对@ Karmajunkie的回答的评论。