Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boolean logic with Rails ENV variables

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?

like image 378
VAD Avatar asked May 05 '17 10:05

VAD


People also ask

Can env variables be boolean?

Environment variables can never be a boolean, they are always a string (or not present).

How do I see environment variables in rails?

Use command ENV in rails console. That will return a hash of your environmental values you can access. Alternatively, you can access your environmental variables from your apps root path using the same command and the variables will be returned formatted.

Are ENV vars always strings?

Also, env variables are always strings.


2 Answers

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.

like image 159
Wikiti Avatar answered Sep 21 '22 07:09

Wikiti


Environment Variables as the name suggests, are environment dependent variables which store different values for same keys based on the environment(production, staging, development) you working on.

e.g. it holds an Access_Key for some api which has sandbox mode and production mode. Thus, to make your code DRY and effective you set an environment variable to get that access_key of sandbox mode for development/staging and live key for production.

What you are trying to do is use them unlike the reason they are defined for, no doubt they can be used that way. Since they are constants what I recommend is doing the following.

create a constants.rb file in your initializers containing

class Constant
  BOOL_CONSTANT = ENV['MY_VARIABLE'].present?
  # OR
  BOOL_CONSTANT = ENV['MY_VARIABLE'] == 'true'
end

then you can use it anywhere you like. This way you can achieve what you want to but under the hood. ;)

like image 38
Md. Farhan Memon Avatar answered Sep 22 '22 07:09

Md. Farhan Memon