我很困惑如何验证Rspec和Rails中的布尔值。我理解除了false
和nil
之外的所有内容都被视为Ruby中的true
。但是当我使用MySQL和Rails时,1
使用true
而0
使用false
(如果我的理解是正确的话)。
我有以下型号规格。我想测试superuser
属性的布尔值。
我的规格和实施代码是否特定于特定数据库(如MySQL和PostgreSQL)?
require 'spec_helper'
describe User do
before(:each) do
@valid_attributes = {
:username => "mike",
:password => "super_encryped_password",
:email => "mike@example.com",
:superuser => true
}
end
it "should create a new instance given valid attributes" do
User.create!(@valid_attributes)
end
it "should have true or false for superuser" do
@valid_attributes[:superuser] = "hello"
User.new(@valid_attributes).should have(1).error_on(:superuser)
end
end
答案 0 :(得分:7)
这是一个很好的讨论,有一些重点:Rails会自动验证布尔字段,false值会导致“状态”验证失败,如果你想确保一个自定义验证,则需要明确查看真假设置boolean field不是nil,但具有真正的true或false值。
Rails 3.x的快速更新是:包含帮助程序:
http://guides.rubyonrails.org/active_record_validations_callbacks.html#inclusion
使用此帮助程序,验证布尔字段的true或false值如下所示:
validates :superuser, :inclusion => {:in => [true, false], :message => 'requires a true or false value' }
该消息是可选的,并且如文档所述,默认为“未包含在列表中”。
在线的共识似乎并不是要明确验证是真还是假,而是要让铁路处理它。然而,我遇到了一种情况,即显式验证在数据库中发现问题(MySql tinyint字段设置为2或4而不是1)导致了一种奇怪的行为。字段可以设置为true或false,但无法将该值作为布尔值读回。换句话说,Rails验证传递了它,但显式包含验证标记了数据库配置错误的所有情况。因此,这可能是一个很好的理由去验证那些条目。 希望这可以帮助。查尔斯
答案 1 :(得分:0)
我想你想要“超级用户应该有真或假”才能失败。但如果您希望它失败,您应该在用户中添加验证:
validate :superuser_boolean
def superuser_boolean
errors.add(:superuser, "Should be a boolean") if !superuser.is_a?(TrueClass) && !superuser.is_a?(FalseClass)
end
答案 2 :(得分:0)
基于jordini的回答:
def superuser_boolean
errors.add(:superuser, "Should be a boolean") if [true, false].include?(superuser)
end
没有丑陋的is_a
支票,只是一个简单的include?
。
答案 3 :(得分:0)
def boolean?(val) !! val == val 端
将其包含在spec_helper中或使用be_boolean
扩展rspec。
答案 4 :(得分:0)
一个重要的事情是ActiveRecord在幕后进行类型转换,因此您不必担心数据库如何存储布尔值。您甚至无需验证字段是否为布尔值,只要在准备迁移时将该字段设置为布尔值即可。您可能希望确保该字段不是nil
,在模型类中使用validates_presence_of :superuser
声明。