Ruby on rails Rails:验证布尔值的包含失败测试
我试图确保我的模型的一个字段是布尔值,但我的测试一直失败 读了这篇文章之后,我就这样做了:Ruby on rails Rails:验证布尔值的包含失败测试,ruby-on-rails,unit-testing,validation,boolean,Ruby On Rails,Unit Testing,Validation,Boolean,我试图确保我的模型的一个字段是布尔值,但我的测试一直失败 读了这篇文章之后,我就这样做了: class Model < ActiveRecord::Base validates :my_field, :inclusion => { :in => [true, false] } end 我错过了什么? 似乎该值是以某种合乎逻辑的方式转换的,但在何处以及如何防止它?如何正确地进行这种验证?我不知道需要将布尔字段验证为真/假的想法是从何而来的,但我最近在一些不相关的项目中看
class Model < ActiveRecord::Base
validates :my_field, :inclusion => { :in => [true, false] }
end
我错过了什么?
似乎该值是以某种合乎逻辑的方式转换的,但在何处以及如何防止它?如何正确地进行这种验证?我不知道需要将布尔字段验证为真/假的想法是从何而来的,但我最近在一些不相关的项目中看到过,所以我开始怀疑这是否是从某个地方开始的模因 它是一个布尔字段,必须为真或假。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]
,因此该模型有效。“false”和“123”失败的原因相同。“true”是布尔值true的一个可接受的值,因此该字段被设置为true,并且基于上面概述的原因仍然有效。我不是Rails专家,但我会在这里指出,您绝对希望验证:inclusion=>{:in=>[true,false]}
--也就是说,假设您不希望允许零(NULL)值
来自数据库编程背景,我学会了记住布尔字段可以有三个值:true、false和NULL。在本机SQL中编程时,null需要特殊处理(为null
而不是=null
),这会导致大量额外工作
在今天的Rails 3.2测试中,创建一个未验证的布尔字段并将其保存到我的PostgreSQL数据库中是没有问题的,在那里它被忠实地存储为NULL。为了避免所有可能导致的问题,我计划对Rails中的布尔函数使用这种方法:
- 在迁移中定义带有
的布尔字段:null=>false
- 使用
验证模型中的字段。如果字段未初始化(nil),这会给出一条很好的消息:inclusion=>{:in=>[true,false]}
一开始我不能使用
:presence
验证不是很直观,但结果是:presence
验证值不是空的,值false
是空的。换句话说,如果验证:presence=>true
,并将值设置为false
,则验证将失败。请参见API和@Paul A Jungwirth对@Karmajunkie答案的评论。谢谢,我不知道假值
/真值
常量。你全面的回答很好地解释了这一点!今天我学到了一些东西。我认为这是因为当一个布尔字段验证了的存在时,只要它是假的,它就会失败。解决方法是在中使用validates\u inclusion\u。我自己也在Rails 3.0.9中看到了这种行为。请看这里:我再次阅读了关于验证的Rails指南,它解释了如何验证布尔字段。我的第一反应是“为什么我要验证布尔值,因为它总是真的或假的,而且永远不会为零?”。为了寻找原因,我偶然发现了这篇文章。我认为模因是从新来者开始的,而且有点卡住了。“如果他们解释怎么做,就应该这样做”。我想这是为了完整而解释的。。。只值我的2美分…这个想法是为了防止字段被nil
,TRUE\u值已被Rails v5删除。查看新代码:我完全同意。我从不希望数据库拒绝插入(非常难看的消息,通常是500个错误),因为它可以被Rails验证捕获,并带有一条用户友好的有用错误消息。很抱歉,我无法为我的model.rb文件找到语法。我尝试过验证的各种变体:property_name、inclusion(true,false)以及:inclusion=>{in=>[true,false]}。你的答案在model.rb文件中使用吗?@flobacca,是的,它在模型中使用,就像原始问题顶部的示例一样。如果它不适合您,您可能需要创建自己的问题,以便显示特定的代码示例。
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set
FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set