-
-
Save equivalent/3825916 to your computer and use it in GitHub Desktop.
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 |
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
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
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
good point, thx for this, I'll update my gits
ok, colleague pointed out that one can use also ActiveRecord::ConnectionAdapters::Column.value_to_boolean("true")
...updating my gits, thx D.D.
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.
I think it is still supported in Rails 4.0
http://www.rubydoc.info/docs/rails/ActiveRecord/ConnectionAdapters/Column.value_to_boolean
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
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
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
ActiveRecord::Type::Boolean.new.type_cast_from_user(value)
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
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
If anybody is coming from Rails 5, this method moved again. I had the most luck with:
ActiveRecord::Type::Boolean.new.cast(string)
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
Thank you! @nickcampbell18 +100
Thank you! @nickcampbell18 +2999
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!
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
@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.
stolen from Jeff Gardner http://jeffgardner.org/2011/08/04/rails-string-to-boolean-method/ ...but with fixed "cat returning true" issue