Skip to content

Instantly share code, notes, and snippets.

@equivalent
Last active December 16, 2021 16:34
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save equivalent/3825916 to your computer and use it in GitHub Desktop.
Save equivalent/3825916 to your computer and use it in GitHub Desktop.
String "false" to_bool ... or how to convert Rails/SimpleForm radio buttons to boolean

This gist was writen in 2012 and it was solving specific problem in Rails & SimpleForm. Some fellow developers were pointing out this may be out dated concept. That's why I advise everyone to read comment section bellow to have a full grasp of alternative solutions

other sources that may be helpful to understand why this may not be best idea:

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
@prodis
Copy link

prodis 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
Copy link
Author

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
Copy link

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

@Genkilabs
Copy link

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
Copy link

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
Copy link

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

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

@isaacbowen
Copy link

@nickooolas
Copy link

@nickcampbell18 thankyou!!!

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

FTW 🥇

@chocolateboy
Copy link

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
Copy link

@kriscard
Copy link

Thank you! @nickcampbell18 +100

@nrogap
Copy link

nrogap commented May 21, 2019

Thank you! @nickcampbell18 +2999

@OpakAlex
Copy link

Please close this gist man, It creates so many issues, i start to see this code into a lot of places, create pr to ruby if you think it's a right way to handle booleans. Thanks a lot!

@equivalent
Copy link
Author

@OpakAlex

i start to see this code into a lot of places

and all are pointing to this gist as a single source ?

create pr to ruby

There is a good reason why this is not introduced in Ruby (or the notion of single boolean class which would TrueClass and FalseClass more info ) But this is not about Ruby it's about specifc usecase in Rails and SimpleForm. It was written in 2012 and it was solving an issue. I cannot tell if it's still valid as I didn't use Simple Form in 8 years but I see people having a conversation on this gist which I think is valuable.

if you think it's a right way to handle booleans

I don't, but this gist is not about Ruby

Please close this gist man

I will not as I see value in the comment section. But I welcome if you drop here a comment guiding others how to better approach issue originally described or your thoughts on boolean in Ruby. I'm pretty sure everyone would welcome a constructive comment with a solution

have a lovely day

@OpakAlex
Copy link

@equivalent if it's not about ruby, then replace:

class TrueClass; include BooleanToBoolean; end
class FalseClass; include BooleanToBoolean; end

and ask people to use your class without patch ruby. I think if it's not about ruby then use helper method or class, or what you want. If you show how to patch standart ruby class, then make ruby PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment