Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
String "false" to_bool ... or how to convert Rails/SimpleForm radio buttons to boolean
module StringToBoolean
def to_bool
return true if self == true || self =~ (/^(true|t|yes|y|1)$/i)
return false if self == false || self.blank? || self =~ (/^(false|f|no|n|0)$/i)
raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
end
end
class String; include StringToBoolean; end
module BooleanToBoolean
def to_bool;return self; end
end
class TrueClass; include BooleanToBoolean; end
class FalseClass; include BooleanToBoolean; end
# However there is also better practice to do it by using
ActiveRecord::ConnectionAdapters::Column.value_to_boolean( something )
2.0.0dev :019 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean('1')
=> true
2.0.0dev :020 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean('0')
=> false
2.0.0dev :021 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean('true')
=> true
2.0.0dev :022 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean('false')
=> false
2.0.0dev :023 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean('nil')
=> false
2.0.0dev :024 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean('t')
=> true
2.0.0dev :025 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean('cat')
=> false
2.0.0dev :026 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean(true)
=> true
2.0.0dev :027 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean(false)
2.0.0dev :035 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean(1)
=> true
2.0.0dev :036 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean(2)
=> false
2.0.0dev :037 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean(0)
=> false
@equivalent

This comment has been minimized.

Copy link
Owner Author

commented Oct 3, 2012

stolen from Jeff Gardner http://jeffgardner.org/2011/08/04/rails-string-to-boolean-method/ ...but with fixed "cat returning true" issue

@equivalent

This comment has been minimized.

Copy link
Owner Author

commented Oct 3, 2012

in rails place the file to config/initializers/string_boolean.rb

than you can do

  "false".to_bool
  #=>  false

Usage: Rails radio button helpers are sending you "false" as string => you need to convert them to boolean, otherwise "false".present? == true

@equivalent

This comment has been minimized.

Copy link
Owner Author

commented Oct 3, 2012

Update: extended with to_bool solution for TrueClass and FalseClass from http://stackoverflow.com/a/3028378/473040

this way you can do

 "false".to_bool #=> false
  false.to_bool  #=> false

and

   def my_method(args)
      if args.is_a? Boolean
         "yahoo it's boolean"
      else
         "is something else"
       end
   end

main reason for implementation is when you have model settra method, that can be set from f.e. simple form radio buttons

    def foo=(arg)
        @foo=arg.to_bool
    end

instead of

 def foo=(arg)
    @foo= (arg.is_a?(TrueClass) || arg.is_a?(FalseClass)) ? arg : (arg == "true" || arg =="yes" ) 
 end
@joe1chen

This comment has been minimized.

Copy link

commented Nov 21, 2012

It turns out that if you're using Mongoid, then Boolean is declared as a class inside of Mongoid. This prevents the gist from working if using Mongoid since it's trying to redefine Boolean as a module. So I've forked the gist and renamed the module Boolean to BooleanToBoolean.

module BooleanToBoolean
  def to_bool;return self; end
end

class TrueClass; include BooleanToBoolean; end
class FalseClass; include BooleanToBoolean; end
@equivalent

This comment has been minimized.

Copy link
Owner Author

commented Feb 19, 2013

good point, thx for this, I'll update my gits

@equivalent

This comment has been minimized.

Copy link
Owner Author

commented Feb 19, 2013

ok, colleague pointed out that one can use also ActiveRecord::ConnectionAdapters::Column.value_to_boolean("true") ...updating my gits, thx D.D.

@jguitar

This comment has been minimized.

Copy link

commented Dec 27, 2013

It seems that ActiveRecord::ConnectionAdapters::Column.value_to_boolean("true") is deprecated
http://apidock.com/rails/ActiveRecord/ConnectionAdapters/Column/value_to_boolean/class
Anyway, thanks for the gist.

@anamartinez

This comment has been minimized.

Copy link

commented Aug 14, 2014

@benlinton

This comment has been minimized.

Copy link

commented Oct 7, 2014

This variation attaches to_bool to most value objects and returns false instead of raising an error when a value isn't expected:

module ToBoolean
  def to_bool
    return true if self == true || self.to_s.strip =~ /^(true|yes|y|1)$/i
    return false
  end
end

class NilClass; include ToBoolean; end
class TrueClass; include ToBoolean; end
class FalseClass; include ToBoolean; end
class Numeric; include ToBoolean; end
class String; include ToBoolean; end

This way:

nil.to_bool           => false
false.to_bool         => false
"false".to_bool       => false
0.to_bool             => false
2.to_bool             => false
"0".to_bool           => false
"2".to_bool           => false
"1.0".to_bool         => false
1.0.to_bool           => false
"no".to_bool          => false
"hamster".to_bool     => false

1.to_bool             => true
"1".to_bool           => true
true.to_bool          => true
"true".to_bool        => true
"true  ".to_bool      => true
"TRUE".to_bool        => true
"  TrUE   ".to_bool   => true
"yes".to_bool         => true
"YES".to_bool         => true
"y".to_bool           => true
"Y".to_bool           => true
@prodis

This comment has been minimized.

Copy link

commented Oct 30, 2014

I have just made the wannabe_bool gem to convert strings, integers, symbols and nil values to boolean, using a #to_b method.
https://github.com/prodis/wannabe_bool

'true'.to_b # => true
1.to_b      # => true
:true.to_b  # => true

'false'.to_b # => false
0.to_b       # => false
:false.to_b  # => false
nil.to_b     # => false

# and more
@equivalent

This comment has been minimized.

Copy link
Owner Author

commented May 20, 2015

ok from Rails 4.2 ActiveRecord::ConnectionAdapters::Column.value_to_boolean("true") is depricated, use:

ActiveRecord::Type::Boolean.new.type_cast_from_database(value)

Works the same way, one different is that type_cast_form_database returns nil when value = nil.

One other thing I've noticed is that if the value is y or n I'm getting:

DEPRECATION WARNING: You attempted to assign a value which is not explicitly `true` or `false` to a boolean column. Currently this value casts to `false`. This will change to match Ruby's semantics, and will cast to `true` in Rails 5. If you would like to maintain the current behavior, you should explicitly handle the values you would like cast to `false`.

... so use only strings "true" and "false" in your radio buttons / check boxes

@karlingen

This comment has been minimized.

Copy link

commented Sep 22, 2015

ActiveRecord::Type::Boolean.new.type_cast_from_user(value)
@Genkilabs

This comment has been minimized.

Copy link

commented Nov 23, 2015

Sometimes I like to be able to call to_bool on something that might be nil, so I alias the Ruby boolean operator default to everything and then further refine String:
app/config/initializers/to_bool.rb

    class Object
        def to_bool
            return !!self
        end
    end

    class String
        def to_bool
            return true if self == true || self =~ (/(true|t|yes|y|1)$/i)
            return false if self == false || self.blank? || self =~ (/(false|f|no|n|0)$/i)
            raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
        end
    end
@jameslafa

This comment has been minimized.

Copy link

commented Apr 26, 2016

Works great for me and seems robust: https://gist.github.com/jameslafa/337e6290115479c2e7e707a8978b7f5a

# config/initializers/to_boolean.rb

module ToBoolean
  def to_bool
    return true if ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES.include?(self)
    return false
  end
end

class NilClass; include ToBoolean; end
class TrueClass; include ToBoolean; end
class FalseClass; include ToBoolean; end
class Numeric; include ToBoolean; end
class String; include ToBoolean; end
@nickcampbell18

This comment has been minimized.

Copy link

commented May 17, 2016

If anybody is coming from Rails 5, this method moved again. I had the most luck with:

ActiveRecord::Type::Boolean.new.cast(string)
@isaacbowen

This comment has been minimized.

Copy link

commented Aug 14, 2016

@nickooolas

This comment has been minimized.

Copy link

commented Mar 10, 2017

@nickcampbell18 thankyou!!!

ActiveRecord::Type::Boolean.new.cast(string)

FTW 🥇

@chocolateboy

This comment has been minimized.

Copy link

commented May 1, 2017

Ruby Facets / to_b

require 'facets/boolean'

[ nil, '', 1, 0, '1', '0', true, false, 'true', 'false', 'yes', 'no' ].each do |value|
  puts "#{value.inspect}: #{value.to_b}"
end

Output

nil: false
"": false
1: true
0: false
"1": true
"0": false
true: true
false: false
"true": true
"false": false
"yes": true
"no": false
@keesbriggs

This comment has been minimized.

Copy link

commented Jun 12, 2018

@kriscard

This comment has been minimized.

Copy link

commented Aug 30, 2018

Thank you! @nickcampbell18 +100

@nrogap

This comment has been minimized.

Copy link

commented May 21, 2019

Thank you! @nickcampbell18 +2999

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.