[ruby] Ruby: How to convert a string to boolean

I have a value that will be one of four things: boolean true, boolean false, the string "true", or the string "false". I want to convert the string to a boolean if it is a string, otherwise leave it unmodified. In other words:

"true" should become true

"false" should become false

true should stay true

false should stay false

This question is related to ruby string boolean type-conversion

The answer is


In rails, I've previously done something like this:

class ApplicationController < ActionController::Base
  # ...

  private def bool_from(value)
    !!ActiveRecord::Type::Boolean.new.type_cast_from_database(value)
  end
  helper_method :bool_from

  # ...
end

Which is nice if you're trying to match your boolean strings comparisons in the same manner as rails would for your database.


If you use Rails 5, you can do ActiveModel::Type::Boolean.new.cast(value).

In Rails 4.2, use ActiveRecord::Type::Boolean.new.type_cast_from_user(value).

The behavior is slightly different, as in Rails 4.2, the true value and false values are checked. In Rails 5, only false values are checked - unless the values is nil or matches a false value, it is assumed to be true. False values are the same in both versions: FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"]

Rails 5 Source: https://github.com/rails/rails/blob/5-1-stable/activemodel/lib/active_model/type/boolean.rb


if value.to_s == 'true'
  true
elsif value.to_s == 'false'
  false
end

In a rails 5.1 app, I use this core extension built on top of ActiveRecord::Type::Boolean. It is working perfectly for me when I deserialize boolean from JSON string.

https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html

# app/lib/core_extensions/string.rb
module CoreExtensions
  module String
    def to_bool
      ActiveRecord::Type::Boolean.new.deserialize(downcase.strip)
    end
  end
end

initialize core extensions

# config/initializers/core_extensions.rb
String.include CoreExtensions::String

rspec

# spec/lib/core_extensions/string_spec.rb
describe CoreExtensions::String do
  describe "#to_bool" do
    %w[0 f F false FALSE False off OFF Off].each do |falsey_string|
      it "converts #{falsey_string} to false" do
        expect(falsey_string.to_bool).to eq(false)
      end
    end
  end
end

A gem like https://rubygems.org/gems/to_bool can be used, but it can easily be written in one line using a regex or ternary.

regex example:

boolean = (var.to_s =~ /^true$/i) == 0

ternary example:

boolean = var.to_s.eql?('true') ? true : false

The advantage to the regex method is that regular expressions are flexible and can match a wide variety of patterns. For example, if you suspect that var could be any of "True", "False", 'T', 'F', 't', or 'f', then you can modify the regex:

boolean = (var.to_s =~ /^[Tt].*$/i) == 0

Working in Rails 5

ActiveModel::Type::Boolean.new.cast('t')     # => true
ActiveModel::Type::Boolean.new.cast('true')  # => true
ActiveModel::Type::Boolean.new.cast(true)    # => true
ActiveModel::Type::Boolean.new.cast('1')     # => true
ActiveModel::Type::Boolean.new.cast('f')     # => false
ActiveModel::Type::Boolean.new.cast('0')     # => false
ActiveModel::Type::Boolean.new.cast('false') # => false
ActiveModel::Type::Boolean.new.cast(false)   # => false
ActiveModel::Type::Boolean.new.cast(nil)     # => nil

Don't think too much:

bool_or_string.to_s == "true"  

So,

"true".to_s == "true"   #true
"false".to_s == "true"  #false 
true.to_s == "true"     #true
false.to_s == "true"    #false

You could also add ".downcase," if you are worried about capital letters.


In Rails I prefer using ActiveModel::Type::Boolean.new.cast(value) as mentioned in other answers here

But when I write plain Ruby lib. then I use a hack where JSON.parse (standard Ruby library) will convert string "true" to true and "false" to false. E.g.:

require 'json'
azure_cli_response = `az group exists --name derrentest`  # => "true\n"
JSON.parse(azure_cli_response) # => true

azure_cli_response = `az group exists --name derrentesttt`  # => "false\n"
JSON.parse(azure_cli_response) # => false

Example from live application:

require 'json'
if JSON.parse(`az group exists --name derrentest`)
  `az group create --name derrentest --location uksouth`
end

confirmed under Ruby 2.5.1


I have a little hack for this one. JSON.parse('false') will return false and JSON.parse('true') will return true. But this doesn't work with JSON.parse(true || false). So, if you use something like JSON.parse(your_value.to_s) it should achieve your goal in a simple but hacky way.


I've frequently used this pattern to extend the core behavior of Ruby to make it easier to deal with converting arbitrary data types to boolean values, which makes it really easy to deal with varying URL parameters, etc.

class String
  def to_boolean
    ActiveRecord::Type::Boolean.new.cast(self)
  end
end

class NilClass
  def to_boolean
    false
  end
end

class TrueClass
  def to_boolean
    true
  end

  def to_i
    1
  end
end

class FalseClass
  def to_boolean
    false
  end

  def to_i
    0
  end
end

class Integer
  def to_boolean
    to_s.to_boolean
  end
end

So let's say you have a parameter foo which can be:

  • an integer (0 is false, all others are true)
  • a true boolean (true/false)
  • a string ("true", "false", "0", "1", "TRUE", "FALSE")
  • nil

Instead of using a bunch of conditionals, you can just call foo.to_boolean and it will do the rest of the magic for you.

In Rails, I add this to an initializer named core_ext.rb in nearly all of my projects since this pattern is so common.

## EXAMPLES

nil.to_boolean     == false
true.to_boolean    == true
false.to_boolean   == false
0.to_boolean       == false
1.to_boolean       == true
99.to_boolean      == true
"true".to_boolean  == true
"foo".to_boolean   == true
"false".to_boolean == false
"TRUE".to_boolean  == true
"FALSE".to_boolean == false
"0".to_boolean     == false
"1".to_boolean     == true
true.to_i          == 1
false.to_i         == 0

Close to what is already posted, but without the redundant parameter:

class String
    def true?
        self.to_s.downcase == "true"
    end
end

usage:

do_stuff = "true"

if do_stuff.true?
    #do stuff
end

Although I like the hash approach (I've used it in the past for similar stuff), given that you only really care about matching truthy values - since - everything else is false - you can check for inclusion in an array:

value = [true, 'true'].include?(value)

or if other values could be deemed truthy:

value = [1, true, '1', 'true'].include?(value)

you'd have to do other stuff if your original value might be mixed case:

value = value.to_s.downcase == 'true'

but again, for your specific description of your problem, you could get away with that last example as your solution.


h = { "true"=>true, true=>true, "false"=>false, false=>false }

["true", true, "false", false].map { |e| h[e] }
  #=> [true, true, false, false] 

Examples related to ruby

Uninitialized Constant MessagesController Embed ruby within URL : Middleman Blog Titlecase all entries into a form_for text field Ruby - ignore "exit" in code Empty brackets '[]' appearing when using .where find_spec_for_exe': can't find gem bundler (>= 0.a) (Gem::GemNotFoundException) How to update Ruby Version 2.0.0 to the latest version in Mac OSX Yosemite? How to fix "Your Ruby version is 2.3.0, but your Gemfile specified 2.2.5" while server starting Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? How to update Ruby with Homebrew?

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to boolean

Convert string to boolean in C# In c, in bool, true == 1 and false == 0? Syntax for an If statement using a boolean Truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all() Ruby: How to convert a string to boolean Casting int to bool in C/C++ Radio Buttons ng-checked with ng-model How to compare Boolean? Convert True/False value read from file to boolean Logical operators for boolean indexing in Pandas

Examples related to type-conversion

How can I convert a char to int in Java? pandas dataframe convert column type to string or categorical How to convert an Object {} to an Array [] of key-value pairs in JavaScript convert string to number node.js Ruby: How to convert a string to boolean Convert bytes to int? Convert dataframe column to 1 or 0 for "true"/"false" values and assign to dataframe SQL Server: Error converting data type nvarchar to numeric How do I convert a Python 3 byte-string variable into a regular string? Leading zeros for Int in Swift