validationRspec和Rails中的布尔值
我很困惑如何validationRspec和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
一个重要的事情是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。