はじめに
rails db:system:change
コマンドはRails6で追加されたコマンドです。
このコマンドにより、Railsが使用するDBをPostgreSQLやMySQL等に簡単に変更できるはずなのですが、試しに実行してみたところ、以下のようなエラーになりました。
% rails db:system:change --to=postgresql
Running via Spring preloader in process 15906
invalid option: --to=postgresql
調査したところ、回避方法や原因がわかったので以下に説明します。
回避方法
Springを無効にすることで回避できます。
SpringはRails6の場合、development環境において標準で有効になっています。
Springにはrailsやrakeコマンドの実行時間を短縮する効果がありますが、マシンスペックの向上に対してその恩恵が少なくなったと判断され、Rails7では標準で無効となりました。
したがって、多くの場合無効にしても問題にならないと思います。
簡単にSpringを無効にする方法は以下です。
1: Gemfileでspringをコメントアウトします。
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 4.1.0'
# Display performance information such as SQL time and flame graphs for each request in your browser.
# Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
gem 'rack-mini-profiler', '~> 2.0'
gem 'listen', '~> 3.3'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
# gem 'spring' # ← ここ
end
2: bundle install
を実行します。
rails db:system:change
コマンドの実行後、再度Springを使いたい場合は、コメントアウトを戻してbundle install
すれば使えます。
原因
GitHubのissueで報告したのですが、直接的な原因はSpringのこの修正です。
全てのdbコマンドに対してrakeが呼び出されるようになっていました。
したがって、以下のコマンドのエラーが表示されていたということになります。
% rake db:system:change --to=postgresql
invalid option: --to=postgresql
db:system:change
は他と違ってrake taskではないためエラーになります。
なお、問題の修正が入ったのはspring gemのv3.1.1からなので、v3.1.0までなら本現象は発生しません。
今後の対処
Spring側を修正する方針になったので、PRを出しておきました。
したがって、今後Spring gemが更新されると修正される見込みです。
ちなみに、この修正にはもう1個問題があって、rails
コマンドを引数なしで実行すると以下のようにNoMethodError
で失敗します。
% rails
Traceback (most recent call last):
12: from bin/rails:2:in `<main>'
11: from bin/rails:2:in `load'
10: from /Users/inayuky/work/rails-postgre/bin/spring:7:in `<top (required)>'
9: from /Users/inayuky/work/rails-postgre/bin/spring:7:in `tap'
8: from /Users/inayuky/work/rails-postgre/bin/spring:10:in `block in <top (required)>'
7: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:83:in `require'
6: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:83:in `require'
5: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/lib/spring/binstub.rb:11:in `<top (required)>'
4: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/lib/spring/binstub.rb:11:in `load'
3: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/bin/spring:49:in `<top (required)>'
2: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/lib/spring/client.rb:30:in `run'
1: from /Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/lib/spring/client/command.rb:7:in `call'
/Users/inayuky/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/spring-4.0.0/lib/spring/client/rails.rb:25:in `call': undefined method `start_with?' for nil:NilClass (NoMethodError)
これもSpringを無効にすることで回避できます。
こちらはこの修正により、将来直るはずです。
なお、Rails7だと標準ではSpringが無効になっていますが、Springを有効にするとRails7でもこれらの現象は発生します。
参考