views:

194

answers:

4

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 => "[email protected]",
          :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  A: 

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
jordinl
Your answer looks pretty good. I didn't come up with `is_a? TrueClass`. I'll look into it.
TK
Matt Briggs
A: 

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?.

Ryan Bigg
What is `is_a?` ugly?
TK
@TK: Yes, and running it twice is to my knowledge slower than checking an include? once.
Ryan Bigg
Thanks. I appreciate your answer.
TK
A: 

Hi there.

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

Include it in your spec_helper or extend rspec with be_boolean.

glebm
A: 

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.

edgerunner
That's the answer I wanted. I don't need to worry about it as long as I set the field boolean. Glad to hear that.
TK
@edgerunner: is that the same in Time columns?
TK
@TK: exactly so.
edgerunner