if Rails.env.production?をやめて、if ENV['ENABLE_HOGEHOGE_FEATURE']のように書いていこう
Rails.envがたくさん生えています。
Rails標準の次の3つと、
- production
- development
- test
Kibelaで定義している次の3つがあります。
- staging
- よくあるstaging用の環境
- heroku
- Herokuで動いているreview apps用の環境
- admin
- otama用の環境
このうち、stagingとherokuをproductionに寄せていきたいと思っています。 adminもどうにかしたい気がしますが、正直あんまり触ってないのでどうにかできるのかがわからない…。でもRails.envの役割ではない気がします。
Rails.envは「Railsというフレームワークの動作モード」です。これは私がどっかで読んだ言葉ですが、一番しっくりきています。
何が言いたいかというと、Rails.envは「環境ごとに機能を出し分けるもの」でも「アクセスするAPIの向き先を変えるもの」でもありません。
そういったものは個別に環境変数で指定しましょう。つまり、コード中にif Rails.env.production?と書くのをやめて、if ENV['ZENDESK_ENABLED']のように書きましょう。
stagingのサーバーでもRails.envがproductionであれば、その分本番との差が少ない状態だと言えます。
より本番に近い環境でstagingサーバーを稼働させるという意味で、その方が正しいのではないでしょうか。
また、if Rails.env.production?をなくして環境変数でアクセスするAPIの向き先などを変えるようにすると、ローカルでproductionとしてrailsアプリを動かすことができるようになります。
これはパフォーマンスの検証やRails.env.production?でしか発生しないバグの調査などに役立つでしょう。
また、単に沢山の環境向けにif文を書くよりも、各環境変数が設定されていることをif文で書いたほうが分かりやすいというのもあります。 例: https://github.com/bitjourney/kibela/blob/5d6148efa2c08e9f63ffb71c09c36fa1ec5c631c/app/models/search_client.rb#L215
# これよりも
if Rails.env.staging? || Rails.env.heroku?
require "faraday_middleware/aws_sigv4"
# ...
end
# こっちのほうが分かりやすい
if ENV['ENABLE_ELASTICSEARCH_SIGV4']
require "faraday_middleware/aws_sigv4"
# ...
endとはいえ、この環境変数をどこで設定すべきなのかという話もあるのですが。
すぐにRails.envを使わないようにコードを全体的に書き換えるのはあまり現実的ではありません。
今Rails.envの数を減らしたところで得られるメリットがそんなに大きいわけでもないですし。
そのため、新規に書くところはRails.envでの分岐をせずに環境変数で設定をしていく形で書くようにして、既存のコードはおいおい……という形が良いのではないかなと思っています。
「Rails.env staging」とかでググるとそれっぽい記事がいくらか出てきます。
querlyのルール