見出し画像

【メモ】RAILS_ENVはコマンドの頭につけておいた方がいいかもしれないという話

はじめに

いつも通りの作業思い出し備忘録です。
先日Redmineのインストール作業を行っていたところ、途中でちょっと引っ掛かったところがあったのでそのメモを。

RAILS_ENVが認識されない

Redmineはproduction環境でしか動かす予定がなかったので、bundle install前に以下のようにbundle configでtestとdevelopmentグループのGemがインストールされないように設定していました。

$ bundle config set --local without 'development test'

その後、unicornの起動や停止をrakeタスクで行えるようにtaskファイルを作成しようとしたところ、以下のようなエラーが発生しました。

$ bundle exec rails g task unicorn RAILS_ENV=production

/home/hoge-user/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/zeitwerk-2.6.1/lib/zeitwerk/kernel.rb:35:in `require': cannot load such file -- listen (LoadError)

zeitwerkはGemfileでdevelopmentグループに指定されているGemで、今回はインストールしていないはずです。
なのに、ここでエラーが発生するのは何か変な感じがしますね。

これを調べたところ、どうやらRAILS_ENVの記述場所がコマンドの末尾であるがために、generate taskのオプションとして解釈されていることが原因のようでした。
(generate taskオプションの第一引数がnamespace、以降の引数が個別のtask名として解釈されるので、そちらに引っ張られているっぽい?)
そのため、本来rails(rake)コマンドの方に掛かるべきであるRAILS_ENVが認識されずデフォルトのdevelopmentとして認識され、zeitwerkをはじめとしたdevelopmentグループのGemを読み込もうとしてLoadErrorが発生したということですね。

なお、『bundle exec rails db:migrate RAILS_ENV=production』などはRAILS_ENVの記述場所がコマンドの末尾でも認識されますが、これはdb:migrateにではなくrailsコマンドの方に掛かっているので意図通りRAILS_ENVを認識してくれるようです。

その後、以下のようにRAILS_ENVをコマンドの先頭に置くことでtaskファイルの作成が行えました。

$ RAILS_ENV=production bundle exec rails g task unicorn

RAILS_ENVを書く場所は今まで割と適当にしていたのですが、これを踏まえるとコマンドの先頭に記述していた方が無難かもしれませんね。

参考リンク

https://qiita.com/shinoharat/items/09d007c9ff5aac7a52c3
https://github.com/rails/rails/blob/f6a8cb42d8a61753efa658c809c5e1673426eb10/guides/source/command_line.md
https://github.com/rails/rails/blob/f95c0b7e96eb36bc3efc0c5beffbb9e84ea664e4/railties/lib/rails/generators/rails/task/USAGE

いいなと思ったら応援しよう!