validationRspec和Rails中的布尔值

我很困惑如何validationRspec和Rails中的布尔值。 我理解除了falsenil之外的所有内容在Ruby中都是true的。 但是当我使用MySQL和Rails时,它使用1表示true0表示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 

一个重要的事情是ActiveRecord在幕后进行类型转换,因此您不必担心数据库如何存储布尔值。 您甚至无需validation字段是否为布尔值,只要在准备迁移时将该字段设置为布尔值即可。 您可能希望确保该字段不是nil ,并在模型类中使用validates_presence_of :superuser声明。

这是一个很好的讨论,有一些重点:Rails会自动validation布尔字段,false值会导致“presence”validation失败,如果你想确保一个布尔字段,那么需要一个明确查找真假设置的自定义validation不是零但具有真正的真假价值。

Rails 3.x的快速更新是:包含帮助程序:

http://guides.rubyonrails.org/active_record_validations_callbacks.html#inclusion

使用此帮助程序,validation布尔字段具有true或false值如下所示:

 validates :superuser, :inclusion => {:in => [true, false], :message => 'requires a true or false value' } 

该消息是可选的,并且如文档所述,将默认为“未包含在列表中”。

在线的共识似乎并不是要明确地validation是真还是假,而是让铁路处理它。 然而,我遇到了一种情况,即显式validation在数据库中发现问题(MySql tinyint字段设置为2或4而不是1)导致了一种奇怪的行为。 字段可以设置为true或false,但无法将该值作为布尔值读回。 换句话说,Railsvalidation通过了它,但显式包含validation标记了数据库配置错误的所有情况。 因此,这可能是一个很好的理由去validation那些条目。 希望这可以帮助。 查尔斯

我想你想要“超级用户应该有真或假”才能失败。 但是如果你想让它失败,你应该在用户中添加一个validation:

 validate :superuser_boolean def superuser_boolean errors.add(:superuser, "Should be a boolean") if !superuser.is_a?(TrueClass) && !superuser.is_a?(FalseClass) end 

基于jordini的答案:

 def superuser_boolean errors.add(:superuser, "Should be a boolean") if [true, false].include?(superuser) end 

没有丑陋的is_a检查,只是一个简单的include?

def boolean?(val)!! val == val end

将它包含在spec_helper中或使用be_boolean扩展rspec。