Validating boolean value in Rspec and Rails

落爺英雄遲暮 提交于 2019-12-10 12:43:17

问题


I'm pretty confused how to validate boolean values in Rspec and Rails. I understand everything except for false and nil are taken as true in Ruby. But when I use MySQL with Rails, it uses 1 for true and 0 for false (if my understanding is correct).

I have the following model spec. I'd like to test boolean value for superuser attribute.

  • How can I write specs here?
  • How can I write implementation code here?
  • Are my specs and implementation code specific to a specific database (like MySQL and 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
    

回答1:


One important thing is that ActiveRecord does typecasting behind the scenes, so you do not have to worry about how your database stores boolean values. You even need not validate that a field is boolean, as long as you set that field as boolean when preparing your migration. You may want to make sure the field is not nil though, with a validates_presence_of :superuser declaration in your model class.




回答2:


This is a great discussion with some important points: Rails validates boolean fields automatically, a false value will cause "presence" validations to fail, and a custom validation looking explicitly for true false settings is needed if you want to make sure a boolean field is not nil but has a genuine true or false value.

A quick update for Rails 3.x is the :inclusion helper:

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

With this helper, validating that a boolean field has a true or a false value looks like this:

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

The message is optional and will, as the documentation notes, default to "is not included in the list."

The consensus online seems to be not to bother validating explicitly for true or false, but to let rails take care of it. I ran into a situation, however, where the explicit validations picked up a problem in the database (MySql tinyint fields were set to 2 or 4 in length instead of 1) that caused a strange behavior. The fields could be set to true or false, but the value could not be read back out as a boolean. In other words, the Rails validation passed it through but the explicit inclusion validation flagged all of those cases where the database was misconfigured. So this might be one good reason to go to the trouble of validating those entries. Hope this helps. Charles




回答3:


I guess you want "should have true or false for superuser" to fail. But if you want it to fail, you should add a validation in the user:

validate :superuser_boolean

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



回答4:


Basing off jordini's answer:

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

No ugly is_a checks, just a simple include?.




回答5:


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

Include it in your spec_helper or extend rspec with be_boolean.



来源:https://stackoverflow.com/questions/3648619/validating-boolean-value-in-rspec-and-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!