Boolean logic with Rails ENV variables

ruby, ruby-on-rails

Solution

You should probably refactor your code and use a custom class, so it's more maintenable and changes may be done easily:

class MyEnv
  TRUTHY_VALUES = %w(t true yes y 1).freeze
  FALSEY_VALUES = %w(f false n no 0).freeze

  attr_reader :value

  def initialize(name)
    @value = ENV[name].to_s.downcase
  end

  def to_boolean
    return true if TRUTHY_VALUES.include?(value.to_s)
    return false if FALSEY_VALUES.include?(value.to_s)
    # You can even raise an exception if there's an invalid value
    raise "Invalid value '#{value}' for boolean casting"
  end
end

# Usage example:
MyEnv.new("MY_VARIABLE").to_boolean

I think that, for boolean environment variables, it's more human-friendly to have values like `yes`, `true`, `no`... instead of present or not present variables.

The only drawback that I can see here is performance, where you jump from nil checking (easy) to a comparisson of strings (a little bit more complex). Give the computer power these days, and if performance is not an issue for you, it would be no problem for you.

So, in conclussion: strings-checks are more human friendly and slower, presence-checks are faster but more obscure.

Problem

Since Rails ENV variables should only have string values it could be the problem to decide how to use ENV variable for use cases which need boolean logic. For example since ENV variable have a string value and it would always be truthy it wouldn't be too nice to do something like that: ``` if ENV['MY_VARIABLE'] # do something else # do something else end ``` So there are at least 2 ways to accomplish things like above: Initialize variable with particular value and check it ``` if ENV['MY_VARIABLE'] == 'some string' # do something elsif ENV['MY_VARIABLE'] == 'some other string' # do something else end ``` Or just initialize variable with any value and check if it was initialized (the code could be exactly as we wanted). ``` if ENV['MY_VARIABLE'] # do something else # do something else end ``` The question is what option is more preferred and what pros and cons each of them could have?

Original source